سرور دومی که همیشه بهروز است
Replication یعنی یک سرور (source) تغییرات را در binlog مینویسد و سرور دیگر (replica) آنها را میخواند و اجرا میکند. کاربردهای رایج: انتقال گزارشهای سنگین مدیریتی به replica تا سایت کند نشود، گرفتن بکاپ از replica، و داشتن سرور آماده برای جایگزینی در صورت خرابی. در replica دو thread کار میکنند: IO thread که رویدادها را از source میگیرد و در relay log مینویسد، و SQL (applier) thread که آنها را اجرا میکند.
GTID به هر تراکنش شناسهای یکتا به شکل server_uuid:شماره میدهد. با GTID دیگر لازم نیست نام فایل و موقعیت binlog را دستی پیدا کنید؛ replica خودش میداند کدام تراکنشها را اجرا کرده و از کجا ادامه دهد (auto-positioning).
پیکربندی
# source: 10.0.0.11
[mysqld]
server_id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
log_bin = binlog
# replica: 10.0.0.12
[mysqld]
server_id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
log_bin = binlog
read_only = ON
super_read_only = ON
relay_log_recovery = ON
-- روی source
CREATE USER 'repl'@'10.0.0.12' IDENTIFIED BY 'Repl-Secret' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.12';
دادهی اولیه را با mysqldump (با --source-data=2 --set-gtid-purged=ON و --all-databases) یا سادهتر با Clone plugin به replica منتقل کنید: CLONE INSTANCE FROM 'clone_user'@'10.0.0.11':3306 IDENTIFIED BY '...'; که کل داده و وضعیت GTID را یکجا کپی میکند.
-- روی replica
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '10.0.0.11',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'Repl-Secret',
SOURCE_AUTO_POSITION = 1,
SOURCE_SSL = 1;
START REPLICA;
SHOW REPLICA STATUS\G
در خروجی، Replica_IO_Running و Replica_SQL_Running باید هر دو Yes باشند. Seconds_Behind_Source تأخیر را نشان میدهد و Last_SQL_Error علت توقف را.
خواندن از replica در برنامه
در جنگو با یک Database Router میتوان گزارشها را به replica فرستاد. حواستان به تأخیر باشد: کاربری که همین الان سفارش ثبت کرده، اگر صفحهی «سفارشهای من» از replica خوانده شود، ممکن است سفارشش را نبیند.
نکتههایی که کمتر کسی میداند
- Replication بکاپ نیست:
DROP TABLEدر کسری از ثانیه روی replica هم اجرا میشود. یک replica تأخیری باSOURCE_DELAY = 3600یک ساعت فرصت نجات میدهد. read_onlyجلوی کاربران دارای SUPER یا CONNECTION_ADMIN را نمیگیرد؛super_read_onlyلازم است تا مدیری اشتباهی روی replica ننویسد.- اگر پوشهی داده یا ماشین مجازی را کپی کردهاید، فایل
auto.cnfرا حذف کنید؛ دو سرور باserver_uuidیکسان رفتارهای عجیب و بیصدا ایجاد میکنند. - با GTID متغیر
sql_replica_skip_counterکار نمیکند؛ برای رد کردن یک تراکنش مشکلدار یک تراکنش خالی با همان GTID تزریق کنید:SET GTID_NEXT='uuid:N'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; Seconds_Behind_Source = 0وقتی IO thread قطع است هم ممکن است دیده شود؛ همیشه وضعیت هر دو thread را با هم پایش کنید.- از 8.0.27 اجرای موازی روی replica با
replica_parallel_workers = 4پیشفرض است و تأخیر را در بار سنگین کم میکند.