1. 程式人生 > 實用技巧 >31. 最大連續子序列和(三)

31. 最大連續子序列和(三)

單臺伺服器在企業業務不斷髮展中必然會遇到訪問壓力與單點故障,主從複製的架構在一定程度上解決了這個問題。一方面可以實現流量分流,可以讓外部請求直接訪問主庫,內部人員訪問從庫;另一方面,從庫可以當做備份伺服器實現主庫故障時的手動切換,以滿足正常執行的基本要求。

主從同步基本原理

  • 主庫開啟binlog日誌記錄功能,主從同步就是從庫去主庫上獲取這個binlog日誌,並且將binlog日誌中記錄執行的SQL語句在從庫上執行一次

  • 從庫上執行start slave命令即可開始主從同步,主從的資料複製就開始了

  • 主從同步開始進行後,從庫上的I/O執行緒就會發送驗證請求到主庫請求建立連線,並指定位置(這個位置是在從庫上執行chage master

    時指定的)後的binlog日誌

  • 主庫在收到從庫的驗證請求後會返回從庫請求的內容,這些內容包括binlog日誌的內容,主庫中新紀錄binlog日誌的名稱以及新的binlog日誌中下一個指定位置點等資訊

  • 從庫收到主庫傳送來的binlog日誌後會將其存在relay log中,並將新的binlog檔名以及位置點資訊儲存在master.info檔案中

  • 從庫的SQL執行緒會實時檢視本地relay log執行緒新增的內容,然後把relay log檔案中的內容解析為SQL語句並順序的在從庫一一執行,最後將當前伺服器中的中繼日誌的檔名及位置點資訊儲存在relay-log.info中以便下次同步需要

主從同步部署

1、伺服器環境配置:

IP 角色 作業系統
106.14.14.122 主資料庫 CentOS7.8
101.132.38.235 從資料庫 CentOS7.8

注意:本篇部落格僅僅是部署測試,現實環境應最大可能使用內網ip。

2、資料庫安裝:

資料庫安裝指令碼

3、主資料庫開始binlog日誌

在主資料庫的配置檔案中新增log_bin,開啟記錄bin_log日誌,檔名為mysql-bin

log_bin=/opt/mysql/data/mysql-bin

重啟資料庫後會發現在/opt/mysql/data目錄中會生成兩個檔案mysql-bin.000001mysql-bin.index

,mysql-bin.000001是記錄binlog日誌的檔案,而index是存放mysql-bin檔名的檔案

[root@mysql-master data]# cat mysql-bin.index 
/opt/mysql/data/mysql-bin.000001

實際同步中,為了安全考慮,主資料庫的使用者授權資訊是不會同步給從庫的,這就必須顯式的在配置檔案中告訴mysql在不要同步mysql庫 。如果binlog-format是ROW模式,那麼忽略同步mysql庫的語法是replicate-wild-ignore-table=mysql.%;如果是STATEMENT模式,語法為replicate-ignore-db=mysql

此項配置需寫在從庫的配置檔案中

mysql> show variables like '%binlog_format%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

binlog 三種格式

ROW

ROW格式會記錄每行記錄修改的記錄,這樣可能會產生大量的日誌內容,比如一條update語句修改了100條記錄,那麼這100條記錄的修改都會被記錄在binlog日誌中,這樣造成binlog日誌量會很大,這種日誌格式會佔用大量的系統資源,mysql5.7和myslq8.0安裝後預設就是這種格式。

STATEMENT

記錄每一條修改資料的SQL語句(批量修改時,記錄的不是單條SQL語句,而是批量修改的SQL語句事件)所以大大減少了binlog日誌量,節約磁碟IO,提高效能,看上面的圖解可以很好的理解row和statement 兩種模式的區別。但是STATEMENT對一些特殊功能的複製效果不是很好,比如:函式、儲存過程的複製。由於row是基於每一行的變化來記錄的,所以不會出現類似問題

MIXED

實際上就是前兩種模式的結合。在Mixed模式下,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。

4、主庫配置同步使用者並對從庫授權

mysql> GRANT REPLICATION SLAVE ON *.* To 'rep'@'101.132.38.235' IDENTIFIED BY '123456';               
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

檢視主庫狀態

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      896 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

5、配置從庫

mysql> CHANGE MASTER TO
    -> MASTER_HOST='106.14.14.122',
    -> MASTER_PORT=3306,
    -> MASTER_USER='rep',
    -> MASTER_PASSWORD='123456',
    -> MASTER_LOG_FILE='mysql-bin.000002',
    -> MASTER_LOG_POS=896;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

檢視從庫同步狀態

mysql> show slave status\G;
*************************** 1. row ***************************
*************************** 略***************************
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
*************************** 略***************************
1 row in set (0.00 sec)

發現Slave_IO_Running: No報錯,檢視日誌發現

2020-07-25T14:18:43.822184Z 6 [ERROR] Slave I/O for channel '': Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). Error_code: 1593

關鍵資訊是說主庫與從庫的server id一樣,因為是指令碼批量安裝,造成了所有伺服器server-id=1,手動將從資料庫的server-id改為2並重啟,再次檢查從庫狀態,發現兩個均為YES。至此,主從同步部署完成。

主從同步測試

主庫建立新庫新表並寫入測試資料

mysql> create database db_test;
Query OK, 1 row affected (0.00 sec)

mysql> use db_test;
Database changed
mysql> CREATE TABLE employees (
    ->     emp_no      INT             NOT NULL COMMENT '主鍵',
    ->     birth_date  DATE            NOT NULL COMMENT '生日',
    ->     first_name  VARCHAR(14)     NOT NULL COMMENT '使用者-姓',
    ->     last_name   VARCHAR(16)     NOT NULL COMMENT '使用者-名',
    ->     gender      ENUM ('M','F')  NOT NULL COMMENT '性別',
    ->     hire_date   DATE            NOT NULL COMMENT '入職時間',
    ->     PRIMARY KEY (emp_no)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO `employees` VALUES 
    -> (10001,'1953-09-02','Georgi','Facello','M','1986-06-26'),
    -> (10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21'),
    -> (10003,'1959-12-03','Parto','Bamford','M','1986-08-28'),
    -> (10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01'),
    -> (10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12'),
    -> (10006,'1953-04-20','Anneke','Preusig','F','1989-06-02'),
    -> (10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10'),
    -> (10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15'),
    -> (10009,'1952-04-19','Sumant','Peac','F','1985-02-18'),
    -> (10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24');
Query OK, 10 rows affected (0.01 sec)
Records: 10  Duplicates: 0  Warnings: 0

登入從庫檢視

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_test            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use db_test;

mysql> show tables;
+-------------------+
| Tables_in_db_test |
+-------------------+
| employees         |
+-------------------+
1 row in set (0.00 sec)

mysql> select * from employees;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10003 | 1959-12-03 | Parto      | Bamford   | M      | 1986-08-28 |
|  10004 | 1954-05-01 | Chirstian  | Koblick   | M      | 1986-12-01 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |
|  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10007 | 1957-05-23 | Tzvetan    | Zielinski | F      | 1989-02-10 |
|  10008 | 1958-02-19 | Saniya     | Kalloufi  | M      | 1994-09-15 |
|  10009 | 1952-04-19 | Sumant     | Peac      | F      | 1985-02-18 |
|  10010 | 1963-06-01 | Duangkaew  | Piveteau  | F      | 1989-08-24 |
+--------+------------+------------+-----------+--------+------------+
10 rows in set (0.00 sec)

資料同步完成