سلام به همه
امروز میخوام یه پست کاملا متفاوت بزارم.
راه اندازی گارد برای posgres . چون نصبمون رو میخوایم از طریق اینترنت انجام بدیم، باید بتونیم به سایت خود postgres بتونیم وصل شیم اما از اونجایی که چوب دو سر طلا هستیم ما it ها، یا از اینور فیلتریم و یا از اونور، بهتره که از آدرس سایت https://shecan.ir برای دور زدن این تحریم استفاده می کنیم.
برای اینکه سیستم عامل مناسب نصب یک پایگاه داده باشد، پکیج preinstall oracle را روی ان نصب می کنیم .برای اینکار باید یکبار دیگر iso را به ماشین مجازی شناساند و انرا mount کرده و در پوشه مربوطه به yum ادرس repository جدید را بصورت زیر داد:
[LocalRepo]
name=LocalRepository
baseurl=file:///cdrom
enabled=1
gpgcheck=0
حالا دستور زیر را می زنیم که این پکیج و متعلقات آن نصب گردد:
yum install oracle-database-*
حالا کارت شبکه دوم را برای اینکه این دو ماشین همدیگر را ببینند آدرس دهیم می کنیم:
cat /etc/sysconfig/network-scripts/ifcfg-enp0s8 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp0s8 UUID=356e52da-1954-430d-9d27-644e99771751 DEVICE=enp0s8 ONBOOT=yes IPADDR=192.168.56.101 NETMASK=255.255.255.0 GATEWAY=192.168.56.103
حالا می توانیم از طریق ssh به هر دو ماشین متصل شویم و مراحل نصب را ادامه دهیم.
در etc/hosts نام ماشینها را وارد می کنیم و همچنین hostname را تنظیم می کنیم
hostnamectl set-hostname abr.vahidnow.lab hostnamectl set-hostname afra.vahidnow.lab
حالا باید مشخصات را در etc/hosts هم اضافه کنیم:
192.168.56.102 abr.vahidnow.lab abr 192.168.56.101 afra.vahidnow.lab afra
در محیط های امن میتوان فایروال را غیر فعال کرد ولی تحت اینترنت باید انرا کانفیگ کرد. ما آنرا در محیط تست غیرفعال می کنیم:
systemctl disable firewalld
همچنین selinux را با disabled می کنیم
vi /etc/selinux/config SELINUX=disabled
حالا دیسکی که به ان شناسانده ایم را disable می کنیم و ماشینها را یکبار ریستارت می کنیم.
به آدرس زیر می رویم و با تنظیم کردن موارد درخواستی خود، لینک لازم را دریافت می کنیم:
https://www.postgresql.org/download/linux/redhat/
موارد زیر را روی هر دو دیتابیس میزنیم:
# Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # Install PostgreSQL: sudo yum install -y postgresql12-server # Optionally initialize the database and enable automatic start: sudo /usr/pgsql-12/bin/postgresql-12-setup initdb sudo systemctl enable postgresql-12 sudo systemctl start postgresql-12
برای اینکه نصبمان درست انجام شود قبل از نصب مابقی چیزها، باید پکیچ زیر را هم از مسیر زیر دانلود کنیم:
https://rpmfind.net/linux/rpm2html/search.php?query=libicuuc.so.50()(64bit)
حالا دستورات داده شده را میزنیم و postgres 12 نصب می شود.
برای اینکه بجز localhost بتوانیم از بیرون ماشین هم به ماشینها وصل بشویم باید دستور زیر را بزنیم:
[root@abr ~]# su - postgres -bash-4.2$ psql -c "alter system set listen_addresses to 'localhost,192.168.56.102'"; ALTER SYSTEM
همینطور این دستور را بر روی سرور دیگر هم میزنیم:
[root@afra ~]# su - postgres -bash-4.2$ psql -c "alter system set listen_addresses to 'localhost,192.168.56.101'"; ALTER SYSTEM
معمولا بعضی جاها بجای اینکار علامت * میزنن به این معنا که روی تمامی کارتهای شبکه listen می شود.
حالا تنظیمات زیر را که مربوط به standby هست را نیر وارد می کنیم:
-bash-4.2$ psql psql (12.6) Type "help" for help. postgres=# alter system set wal_level = replica ; ALTER SYSTEM postgres=# alter system set max_wal_senders = 3 ; ALTER SYSTEM postgres=# alter system set max_wal_size = '200MB'; ALTER SYSTEM postgres=# alter system set wal_keep_segments = 8 ; ALTER SYSTEM postgres=# alter system set hot_standby = on; ALTER SYSTEM postgres=# alter system set hot_standby_feedback = on; ALTER SYSTEM
برای اینکه تنظیمات ما در فایل مربوطه بنشیند دستور زیر را می زنیم:
postgres=# select pg_reload_conf(); pg_reload_conf ---------------- t (1 row)
برخی از دستوراتی که زدیم هنوز اعمال نشده است و برای آن باید postgres را ریست کنیم. مثلا با دستور زیر می فهمیم که listen_adresses هنوز اعمال نشده است:
postgres=# show listen_addresses; listen_addresses ------------------ localhost (1 row)
برای اینکه ببینیم فایلهای کانفیگ در کجا قرار دارند می توان از دستور زیر استفاده کرد:
postgres=# show hba_file; hba_file ------------------------------------ /var/lib/pgsql/12/data/pg_hba.conf (1 row)
در این فایل باید آدرس دیتابیس استندبای را بصورت زیر وارد کنیم:
host replication replication 192.168.56.102/32 md5
حالا یکبار postgres را ریستارت می کنیم تا تنظیمات مدنظرمان اعمال شود:
[root@afra ~]# systemctl restart postgresql-12 [root@afra ~]# su - postgres Last login: Mon May 3 07:31:22 EDT 2021 on pts/0 -bash-4.2$ psql psql (12.6) Type "help" for help. postgres=# show listen_addresses; listen_addresses -------------------------- localhost,192.168.56.101 (1 row)
همانطور که می بینیم حالا listen_addresses به تنظیمات مد نظر ما تغییر می کند.
حالا به سراغ دیتابیس استندبای می رویم . این دیتابیس باید در حالت stop و دایرکتوری data آن خالی باشد.
[root@abr ~]# systemctl status postgresql-12 ● postgresql-12.service - PostgreSQL 12 database server Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; enabled; vendor preset: disabled) Active: inactive (dead) since Mon 2021-05-03 09:48:06 EDT; 7s ago ... [root@abr ~]# su - postgres Last login: Mon May 3 07:28:09 EDT 2021 on pts/0 -bash-4.2$ cd 12/ backups/ data/ initdb.log -bash-4.2$ cd 12/ -bash-4.2$ mv data data_old
حالا بر روی دیتابیس اصلی کاربری می سازیم که توسط آن عملیات replication انجام شود:
postgres=# create user replication REPLICATION LOGIN CONNECTION LIMIT 5 ENCRYPTED PASSWORD 'password123' ; CREATE ROLE postgres=# \du List of roles Role name | Attributes | Member of -------------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} replication | Replication +| {} | 5 connections |
روی سرور استندبای برای اینکه دیتابیس استندبای ساخته شود دستور زیر را میزنیم:
pg_basebackup -h 192.168.56.101 -D /var/lib/pgsql/12/data -U replication -P -v –R
در آن h نشان آدرس D نشان دایرکتوری U نشان کاربری که برای replication تعریف کردیم. P نشان دهنده progress و v برای توضیح بیشتر در مورد کار در حال انجام و R که از 12 آمده است برای اینکه اطلاعات مربوط به استندبای را بصورت اتوماتیک ایجاد کند.
-bash-4.2$ pg_basebackup -h 192.168.56.101 -D /var/lib/pgsql/12/data -U replication -P -v -R Password: pg_basebackup: initiating base backup, waiting for checkpoint to complete pg_basebackup: checkpoint completed pg_basebackup: write-ahead log start point: 0/2000028 on timeline 1 pg_basebackup: starting background WAL receiver pg_basebackup: created temporary replication slot "pg_basebackup_13822" 25315/25315 kB (100%), 1/1 tablespace pg_basebackup: write-ahead log end point: 0/2000100 pg_basebackup: waiting for background process to finish streaming ... pg_basebackup: syncing data to disk ... pg_basebackup: base backup completed
با توجه به اینکه دیتابیس ما کوچک بود و حجمی نداشت، اینکار به سرعت انجام شد.
حالا اگر دوباره دستور ls را بزنیم، می بینیم که دایرکتوری data ایجاد شده است و اگر داخل آن برویم، می بینیم که فایلی با نام postgresql.auto.conf ایجاد شده که محتویات آن بصورت اتوماتیک با دستور قبل و ذکر دستور R ایجاد شده است.
-bash-4.2$ ls backups data data_old initdb.log -bash-4.2$ cd data -bash-4.2$ ls backup_label log pg_ident.conf pg_replslot pg_stat_tmp PG_VERSION postgresql.conf base pg_commit_ts pg_logical pg_serial pg_subtrans pg_wal standby.signal current_logfiles pg_dynshmem pg_multixact pg_snapshots pg_tblspc pg_xact global pg_hba.conf pg_notify pg_stat pg_twophase postgresql.auto.conf -bash-4.2$ cat postgresql.auto.conf # Do not edit this file manually! # It will be overwritten by the ALTER SYSTEM command. listen_addresses = 'localhost,192.168.56.101' wal_level = 'replica' max_wal_senders = '3' max_wal_size = '200MB' wal_keep_segments = '8' hot_standby = 'on' hot_standby_feedback = 'on' primary_conninfo = 'user=replication password=password123 host=192.168.56.101 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
حالا روی سرور استندبای postgres را استارت می کنیم و آنرا چک می کنیم:
[root@abr ~]# systemctl status postgresql-12 ● postgresql-12.service - PostgreSQL 12 database server Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2021-05-03 10:12:16 EDT; 5s ago Docs: https://www.postgresql.org/docs/12/static/ Process: 2963 ExecStartPre=/usr/pgsql-12/bin/postgresql-12-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) Main PID: 2969 (postmaster) CGroup: /system.slice/postgresql-12.service ├─2969 /usr/pgsql-12/bin/postmaster -D /var/lib/pgsql/12/data/ ├─2971 postgres: logger ├─2972 postgres: startup recovering 000000010000000000000003 ├─2973 postgres: checkpointer ├─2974 postgres: background writer ├─2975 postgres: stats collector └─2976 postgres: walreceiver streaming 0/3000148 May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.817 EDT [2969] LOG: listening on IP...5432 May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.817 EDT [2969] LOG: listening on IP...5432 May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.819 EDT [2969] LOG: could not bind ...ress May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.819 EDT [2969] HINT: Is another pos...try. May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.819 EDT [2969] WARNING: could not c...101" May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.819 EDT [2969] LOG: listening on Un...432" May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.821 EDT [2969] LOG: listening on Un...432" May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.828 EDT [2969] LOG: redirecting log...cess May 03 10:12:15 abr.vahidnow.lab postmaster[2969]: 2021-05-03 10:12:15.828 EDT [2969] HINT: Future log out...og". May 03 10:12:16 abr.vahidnow.lab systemd[1]: Started PostgreSQL 12 database server. Hint: Some lines were ellipsized, use -l to show in full.
خط highlight شده نشان می دهد که در حال دریافت wal ها هست از سمت دیتابیس اصلی
اگر دستور Status را روی دیتابیس اصلی بزنیم :
[root@afra ~]# systemctl status postgresql-12 ● postgresql-12.service - PostgreSQL 12 database server Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; enabled; vendor preset: disabled) Active: active (running) since Mon 2021-05-03 09:44:28 EDT; 30min ago Docs: https://www.postgresql.org/docs/12/static/ Process: 12892 ExecStartPre=/usr/pgsql-12/bin/postgresql-12-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) Main PID: 12897 (postmaster) CGroup: /system.slice/postgresql-12.service ├─12897 /usr/pgsql-12/bin/postmaster -D /var/lib/pgsql/12/data/ ├─12900 postgres: logger ├─12902 postgres: checkpointer ├─12903 postgres: background writer ├─12904 postgres: walwriter ├─12905 postgres: autovacuum launcher ├─12906 postgres: stats collector ├─12907 postgres: logical replication launcher └─14335 postgres: walsender replication 192.168.56.102(35812) streaming 0/3000148
می گوید که در حال ارسال wal هاست
برای دیدن دایرکتوری های مرتبط با لاگ و دیتا دستور زیر را می توانیم بزنیم:
-bash-4.2$ psql psql (12.6) Type "help" for help. postgres=# show log_directory; log_directory --------------- log (1 row) postgres=# show data_directory; data_directory ------------------------ /var/lib/pgsql/12/data (1 row)
حالا به مسیر زیر می رویم
-bash-4.2$ cd /var/lib/pgsql/12/data/log
فایلهای موجود را می بینیم:
-bash-4.2$ ls -ltrho total 8.0K -rw------- 1 postgres 186 May 3 10:01 postgresql-Thu.log -rw------- 1 postgres 0 May 3 10:01 postgresql-Sun.log -rw------- 1 postgres 0 May 3 10:01 postgresql-Sat.log -rw------- 1 postgres 0 May 3 10:01 postgresql-Fri.log -rw------- 1 postgres 2.7K May 3 10:12 postgresql-Mon.log
فایلی که در حال کار است را نگاه می کنیم:
-bash-4.2$ tailf postgresql-Mon.log 2021-05-03 09:44:28.259 EDT [6161] LOG: shutting down 2021-05-03 09:44:28.268 EDT [6155] LOG: database system is shut down 2021-05-03 09:44:28.299 EDT [12901] LOG: database system was shut down at 2021-05-03 09:44:28 EDT 2021-05-03 09:44:28.304 EDT [12897] LOG: database system is ready to accept connections 2021-05-03 10:12:15.830 EDT [2972] LOG: database system was interrupted; last known up at 2021-05-03 10:01:57 EDT 2021-05-03 10:12:16.106 EDT [2972] LOG: entering standby mode 2021-05-03 10:12:16.108 EDT [2972] LOG: redo starts at 0/2000028 2021-05-03 10:12:16.109 EDT [2972] LOG: consistent recovery state reached at 0/2000100 2021-05-03 10:12:16.109 EDT [2969] LOG: database system is ready to accept read only connections 2021-05-03 10:12:16.114 EDT [2976] LOG: started streaming WAL from primary at 0/3000000 on timeline 1
همانطور که در خط آخر می بنیم در حال گرفتن wal ها از سمت دیتابیس اصلی است.
حالا برای تست سیستممان به دیتابیس اصلی وصل می شویم
-bash-4.2$ psql psql (12.6) Type "help" for help.
با دستور \l لیست دیتابیسهای موجود را می گیریم:
postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows)
یک دیتابیس جدید می سازیم و دوباره لیست دیتابیس ها را می گیریم:
postgres=# create database rahnama; CREATE DATABASE postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | rahnama | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows) postgres=# checkpoint; CHECKPOINT
حالا روی دیتابیس استندبای نگاه می کنیم ببینیم که این دیتابیس جدید آمده است یا خیر؟
-bash-4.2$ psql psql (12.6) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | rahnama | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows)
حالا جدول جدیدی روی دیتابیس جدید می سازیم:
postgres-# \c rahnama; You are now connected to database "rahnama" as user "postgres". rahnama-# create table test1 (f1 int); ERROR: syntax error at or near "psql" LINE 1: psql ^ rahnama=# create table test1 (f1 int); CREATE TABLE rahnama=# insert into test1 values (3); INSERT 0 1 rahnama=# insert into test1 values (7); INSERT 0 1
حالا اگر در استندبای این جدول را از دیتابیس جدید جستجو کنیم می بینیم که انتقال یافته است:
postgres=# \c rahnama; You are now connected to database "rahnama" as user "postgres". rahnama=# select * from test1; f1 ---- 3 7 (2 rows)
حالا در سمت سیستم عامل از کجا بدانیم که دیتابیس حاضر و نصب شده روی این سیستم، آِیا اصلی هست یا استندبای؟
یک نشانه برای دیتابیس اصلی بودن وجود پروسس walsender است.
-bash-4.2$ ps -ef | grep "walsender" postgres 14335 12897 0 10:12 ? 00:00:00 postgres: walsender replication 192.168.56.102(35812) streaming 0/3013BC0
این پروسس بر روی استندبای وجود ندارد. در عوض روی استندبای walreceiver وجود دارد.
-bash-4.2$ ps -ef | grep "walreceiver" postgres 2976 2969 0 10:12 ? 00:00:01 postgres: walreceiver streaming 0/3013BC0
در سطح دیتابیس هم می توان با جستجوی زیر متوجه وضعیت دیتابیس از لحاظ اصلی یا استندبای شد.
postgres=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- t (1 row)
جواب جستجوی بالا روی اصلی f و روی استندبای t است.
با دستور زیر می توانیم اطلاعات زیادی در مورد وضعیت replication ببینیم:
postgres=# \x Expanded display is on. postgres=# select * from pg_stat_replication; -[ RECORD 1 ]----+------------------------------ pid | 14335 usesysid | 16384 usename | replication application_name | walreceiver client_addr | 192.168.56.102 client_hostname | client_port | 35812 backend_start | 2021-05-03 10:12:16.271135-04 backend_xmin | 491 state | streaming sent_lsn | 0/3013BC0 write_lsn | 0/3013BC0 flush_lsn | 0/3013BC0 replay_lsn | 0/3013BC0 write_lag | flush_lag | replay_lag | sync_priority | 0 sync_state | async reply_time | 2021-05-03 10:50:18.826827-04
برای اینکه ببینیم در حال حاضر چه wal ی در حال کار است این دستور را روی دیتابیس اصلی می زنیم:
postgres=# select pg_current_wal_lsn(); -[ RECORD 1 ]------+---------- pg_current_wal_lsn | 0/3013BC0
برای اینکه ببینیم کدام wal در حال دریافت است دستور زیر را می زنیم:
postgres=# select pg_last_wal_receive_lsn(); pg_last_wal_receive_lsn ------------------------- 0/3013BC0 (1 row)
برای اینکه ببینیم کدام wal در حال apply شدن است از دستور زیر استفاده می کنیم:
postgres=# select pg_last_wal_replay_lsn(); pg_last_wal_replay_lsn ------------------------ 0/3013BC0 (1 row)
در صورتی که بخواهیم apply روی استندبای متوقف شود، با دستور زیر اینکار را انجام می دهیم:
postgres=# select pg_wal_replay_pause(); pg_wal_replay_pause --------------------- (1 row)
دستور بالا به این معنی است که apply نمی کند اما همچنان فایلهای wal را دریافت می کند.
postgres=# select pg_wal_replay_resume(); pg_wal_replay_resume ---------------------- (1 row)
دستور بالا دوباره apply کردن را ادامه می دهد.
اگر بخواهیم در دیتابیس استندبای کار dml یا ddl انجام دهیم به ما خطای زیر را میدهد:
postgres=# create database test; ERROR: cannot execute CREATE DATABASE in a read-only transaction postgres=# \q
برای failover کردن دیتابیس به راحتی با دستور زیر می توان اینکار را انجام داد
-bash-4.2$ /usr/pgsql-12/bin/pg_ctl promote -D /var/lib/pgsql/12/data waiting for server to promote.... done server promoted
همزمان در لاگ این خطوط را مشاهده می کنیم:
2021-05-03 13:25:26.104 EDT [2972] LOG: received promote request 2021-05-03 13:25:26.104 EDT [2976] FATAL: terminating walreceiver process due to administrator command 2021-05-03 13:25:26.105 EDT [2972] LOG: invalid record length at 0/3013BC0: wanted 24, got 0 2021-05-03 13:25:26.105 EDT [2972] LOG: redo done at 0/3013B88 2021-05-03 13:25:26.105 EDT [2972] LOG: last completed transaction was at log time 2021-05-03 10:30:49.561324-04 2021-05-03 13:25:26.118 EDT [2972] LOG: selected new timeline ID: 2 2021-05-03 13:25:26.330 EDT [2972] LOG: archive recovery complete 2021-05-03 13:25:26.345 EDT [2969] LOG: database system is ready to accept connections
تمام شد. به همین راحتی . حالا تست می کنیم این دیتابیس را:
-bash-4.2$ psql psql (12.6) Type "help" for help. postgres=# create database test; CREATE DATABASE postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | rahnama | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres test | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | (5 rows)
- ۰۰/۰۸/۱۵
خیلی عالی و کاربردی بود
ممنون مهندس