(學習到實踐)4、docker搭建mysql主從實踐

前言

目前已完成:php7及擴展、redis5的Dockerfile測試版編寫,稍許完善後同步上傳到github,(記下這裏memcached尚未剝離安裝)。
今天數據庫,編程的一個重要原則是不要重複造輪子,php由於須要不少自定義插件、因此單獨編譯鏡像,其實其餘包括redis都應該使用官方的,直接pull就行。php


參考官方鏡像,根據官方鏡像,準備的mysql、mysql_slave文件樹,添加了個數據文件夾。html

[]:~/tmp/dk/mysql/mysql_slave# tree ./
./
├── config
│   ├── conf.d #後面修改my.cnf後刪掉
│   │   └── docker.cnf
│   └── my.cnf
└── data

一、建立mysql鏡像

[]:~/tmp/dk# docker pull mysql:8.0
# 清空舊數據庫數據
[]:~/tmp/dk# rm -rf /root/tmp/dk/mysql/data/* /root/tmp/dk/mysql_slave/data/*
[]:~/tmp/dk# docker run --name mm -p 3306:3306 \
    -v /root/tmp/dk/mysql/data:/var/lib/mysql \
    -v /root/tmp/dk/mysql/config:/etc/mysql \
    -e MYSQL_ROOT_PASSWORD=123456  -d mysql:8.0
[]:~/tmp/dk# docker run --name ms -p 3308:3306 \
    -v /root/tmp/dk/mysql_slave/data:/var/lib/mysql \
    -v /root/tmp/dk/mysql_slave/config:/etc/mysql \
    -e MYSQL_ROOT_PASSWORD=123456  -d mysql:8.0

退出後臺運行的容器,按 Ctrl+D 進行退出容器,請牢記!
run後運行的容器進入:mysql

a.舊式進入     []:~/tmp/dk# docker attach mm
b.命令進入     []:~/tmp/dk# docker exec -it mm /bin/bash(或/bin/sh)

參考《Docker容器進入的4種方式
a.普通進入:有一個問題。當多個窗口同時使用該命令進入該容器時,全部的窗口都會同步顯示。若是有一個窗口阻塞了,那麼其餘窗口也沒法再進行操做。因此docker attach命令不太適合於生產環境,平時本身開發應用時可使用該命令。
b.推薦git

-- 小內存主機須要開啓swap交換分區,並加入開機啓動:github

[]:~/tmp/dk# vim /etc/rc.local 
# +swap
swapon /swapfile

-- mysql的重啓:
不能進入容器、在容器中重啓,會報 Unable to lock ./ibdata1 error: 11 的錯誤,容器沒法對共享文件加鎖。redis

# 重啓mysql容器
[]:~# docker restart mm

二、mysql配置

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
datadir         = /var/lib/mysql

# 主從賦值增長項
log-bin=mysql-bin        #[必須]啓用二進制日誌
server-id=1              #[必須]服務器惟一ID,默認是1
binlog-do-db=test            #要同步的數據庫名,從服務器不須要這幾項
binlog-ignore-db = mysql     #不一樣步mysql庫和sys庫
binlog-ignore-db = sys
replicate-ignore-db=mysql
secure-file-priv= NULL
# 忽略表名大小寫
lower_case_table_names        = 1

character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
#是否對sql語句大小寫敏感,1表示不敏感
lower_case_table_names=1

#最大鏈接數
max_connections = 150
#最大錯誤鏈接數
max_connect_errors=1000
#TIMESTAMP若是沒有顯示聲明NOT NULL,容許NULL值
explicit_defaults_for_timestamp=true

#SQL數據包發送的大小,若是有BLOB對象建議修改爲1G
max_allowed_packet=2M
#MySQL鏈接閒置超過必定時間後(單位:秒)將會被強行關閉
#MySQL默認的wait_timeout  值爲8個小時, interactive_timeout參數須要同時配置才能生效
interactive_timeout = 1800
wait_timeout = 1800

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

#時區
default-time_zone = '+8:00'

三、主從同步數據

在主服務器添加用於同步的帳戶。上須要主從服務器端配合完成sql

a.初始化同步用戶

### 主服務器端
mysql> CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'Ron_master_1';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      825 | test         | mysql,sys        |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

b.手動同步初始數據

添加測試數據,適合從一臺拓展至多臺服務器的狀況。若是庫數據已同步,跳過此步驟。
如今master中已有數據,須要先同步到slave,登陸master,執行鎖表操做docker

### 容器mm(master)主服務器添加初始庫、表,及後續操做
mysql> create database test;
Query OK, 1 row affected (0.01 sec)

mysql> use test
Database changed
mysql> create table sys ( id int unsigned auto_increment primary key, `column` varchar(255) not null );
Query OK, 0 rows affected (0.03 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1272 | test         | mysql,sys        |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#只讀鎖表,等待複製
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)
# 等待主從關係創建完成後,解鎖寫入
mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)
### 容器ms(slave):從服務器導入master的庫數據
xx@fd8bb25a86fc:/# mysql -uroot -p123456
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> quit
Bye
root@fd8bb25a86fc:/# mysqldump -uroot -p -h remote_host -P3306 test > /tmp/test.dump
Enter password: 
# 或直接use而後source file
root@fd8bb25a86fc:/# mysql -u root -p test < /tmp/test.dump

c.創建主從關係,完成同步

這裏須要注意的參數是master_log_file、master_log_pos改成與master當前值相同。數據庫

### 容器ms(slave):從服務器添加
# 查詢當前狀態:show slave status\G; 重置複製狀態參數:reset slave all; 關閉:stop slave;
# remote_host能夠是 192.168.1.102 的內網、公網地址
mysql> change master to master_host='remote_host',master_port=3306,master_user='repl',\
    master_password='Ron_master_1',master_log_file='mysql-bin.000003',master_log_pos=1272;
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_State: Waiting for master to send event
                  Master_Host: xx.xx.xx.xx 
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1272
               Relay_Log_File: 6e9640cfaa53-relay-bin.000003
                Relay_Log_Pos: 322
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
... ...

Slave_IO_Running和 Slave_SQL_Running都是Yes,說明主從複製已經開啓成功。編程

小結

這其中遇到不少問題,好比:mysql的容器沒法啓動(配置文件問題,或使用現成配置好的,經過docker logs mm查看日誌解決),沒法從內部重啓(搜索良久,應該是官方的問題,也確實沒有從外部方便,只是對不是用mysql命令restart的彆扭而已),主從複製沒好(要點:my.cnf配置,鎖表/肯定不寫入也行,master_log_file、master_log_pos參數)。之前只是看過些,浮於理論,實踐完成後才感受通暢。

相關文章
相關標籤/搜索