ПРОЦЕСС КОНТРОЛЬНОЙ ТОЧКИ ~~~~~~~~~~~~~~~~~~~~~~~~~ Заглянем в статистику: => \x Expanded display is on. => select * from pg_stat_bgwriter; -[ RECORD 1 ]---------+------------------------------ checkpoints_timed | 0 checkpoints_req | 4 checkpoint_write_time | 3 checkpoint_sync_time | 1 buffers_checkpoint | 5 buffers_clean | 3037 maxwritten_clean | 7 buffers_backend | 170 buffers_backend_fsync | 0 buffers_alloc | 4642 stats_reset | 2017-12-14 18:58:19.553712+03 * checkpoints_timed - контрольные точки по расписанию (checkpoint_timeout); * checkpoints_req - контрольные точки по требованию (max_wal_size); * checkpoint_write_time - общее время записи на диск, мс; * checkpoint_sync_time - общее время синхронизации с диском, мс; * buffers_checkpoint - число страниц, записанных при контрольных точках. ....................................................................... УПРАВЛЯЮЩИЙ ФАЙЛ ~~~~~~~~~~~~~~~~ Заглянем в управляющий файл $PGDATA/global/pg_control. Это можно сделать с помощью утилиты pg_controldata. Мы увидим много справочной информации, а также данное о последней контрольной точке. Обратите внимание и на статус кластера: "in production". ....................................................................... pg_controldata pg_control version number: 942 Catalog version number: 201510051 Database system identifier: 6286408245735415780 Database cluster state: in production pg_control last modified: Чт. 14 дек. 2017 18:59:00 Latest checkpoint location: 3/B35D50E8 Prior checkpoint location: 3/B35D32E4 Latest checkpoint's REDO location: 3/B35D50E8 Latest checkpoint's REDO WAL file: 0000001100000003000000B3 Latest checkpoint's TimeLineID: 17 Latest checkpoint's PrevTimeLineID: 17 Latest checkpoint's full_page_writes: on Latest checkpoint's NextXID: 0/557772 Latest checkpoint's NextOID: 126927 Latest checkpoint's NextMultiXactId: 6 Latest checkpoint's NextMultiOffset: 11 Latest checkpoint's oldestXID: 656 Latest checkpoint's oldestXID's DB: 1 Latest checkpoint's oldestActiveXID: 0 Latest checkpoint's oldestMultiXid: 1 Latest checkpoint's oldestMulti's DB: 1 Latest checkpoint's oldestCommitTsXid:0 Latest checkpoint's newestCommitTsXid:0 Time of latest checkpoint: Чт. 14 дек. 2017 18:59:00 Fake LSN counter for unlogged rels: 0/1 Minimum recovery ending location: 0/0 Min recovery ending loc's timeline: 0 Backup start location: 0/0 Backup end location: 0/0 End-of-backup record required: no wal_level setting: minimal wal_log_hints setting: off max_connections setting: 100 max_worker_processes setting: 8 max_prepared_xacts setting: 0 max_locks_per_xact setting: 64 track_commit_timestamp setting: off Maximum data alignment: 4 Database block size: 8192 Blocks per segment of large relation: 131072 WAL block size: 8192 Bytes per WAL segment: 16777216 Maximum length of identifiers: 64 Maximum columns in an index: 32 Maximum size of a TOAST chunk: 2000 Size of a large-object chunk: 2048 Date/time type storage: 64-bit integers Float4 argument passing: by value Float8 argument passing: by reference Data page checksum version: 0 ....................................................................... Выполним вручную контрольную точку и посмотрим, как это отражается в журнале и управляющем файле. => select pg_current_xlog_location() as start_lsn \gset => \setenv START_LSN :start_lsn => select pg_xlogfile_name(:'start_lsn') as start_seg \gset => \setenv START_SEG :start_seg => checkpoint; CHECKPOINT => select pg_current_xlog_location() as end_lsn \gset => \setenv END_LSN :end_lsn ....................................................................... В журнал попадает отметка о том, что контрольная точка начата: => \! pg_xlogdump -p $PGDATA/pg_xlog -s $START_LSN -e $END_LSN $START_SEG rmgr: XLOG len (rec/tot): 76/ 102, tx: 0, lsn: 3/B35D519C, prev 3/B35D5174, desc: CHECKPOINT_ONLINE redo 3/B35D519C; tli 17; prev tli 17; fpw true; xid 0/557772; oid 126927; multi 6; offset 11; oldest xid 656 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 0; online ....................................................................... Сравним с данными управляющего файла: Latest checkpoint's REDO location: 3/B35D519C Latest checkpoint's REDO WAL file: 0000001100000003000000B3 Данные о LSN, очевидно, совпадают. ....................................................................... ВОССТАНОВЛЕНИЕ ~~~~~~~~~~~~~~ Теперь эмулируем сбой. Для этого создадим таблицу и принудительно выключим сервер. => create database db9; CREATE DATABASE => \c db9 You are now connected to database "db9" as user "postgres". => create table test(t text); CREATE TABLE => insert into test values ('Перед сбоем'); INSERT 0 1 => \q pg_ctl stop -w -m immediate waiting for server to shut down... done server stopped ....................................................................... Сейчас на диске находятся журнальные записи, но табличная страница (как и страницы системного каталога) не были сброшены на диск. Проверим состояние кластера: Database cluster state: in production Оно не изменилось - при запуске PostgreSQL поймет, что имеет место рассогласование данных и выполнит восстановление. ....................................................................... pg_ctl start -w -l /home/postgres/logfile waiting for server to start..... done server started tail -n 10 /home/postgres/logfile LOG: database system was interrupted; last known up at 2017-12-14 18:59:01 MSK FATAL: the database system is starting up LOG: database system was not properly shut down; automatic recovery in progress LOG: redo starts at 3/B35D75B0 LOG: invalid record length at 3/B35F2E2C LOG: redo done at 3/B35F2E08 LOG: last completed transaction was at log time 2017-12-14 18:59:01.159665+03 LOG: MultiXact member wraparound protections are now enabled LOG: database system is ready to accept connections LOG: autovacuum launcher started ....................................................................... psql => \c db9 You are now connected to database "db9" as user "postgres". => select * from test; t ------------- Перед сбоем (1 row) Как видим, таблица и данные восстановлены. ....................................................................... Теперь остановим экземпляр с выполнением контрольной точки: => \q pg_ctl stop -w -m fast waiting for server to shut down.... done server stopped Проверим состояние кластера: Database cluster state: shut down Теперь оно - "shut down", что соответствует корректной остановке. ....................................................................... Конец демонстрации. ....................................................................... pg_ctl start -w -l /home/postgres/logfile waiting for server to start.... done server started