【RDB】MariaDB 之事務、複製、集羣

目錄

  • 簡介
  • 安裝啓動
  • 權限
  • 事務
    • 髒讀、不可重複讀、幻讀
    • MVCC
  • 複製
    • 異步複製
    • 半同步複製
    • GTID複製
  • 集羣(Galera)
  • 配置
  • 監控(Zabbix)

簡介

環境:html

  • CentOS 7.4.1708
  • MariaDB 10.3.9

簡介:mysql

  • MySQL 由 MySQLAB 公司開發。
  • MariaDB 是 MySQL的一個分支,它是 MySQL 之父 Monty Widenius 開發
  • 目前不少知名的 Linux 發行版已經使用 MariaDB 替代了 MySQL。如:RHEL 7,CentOS 7。

MariaDB的優勢:sql

  • 插件式存儲引擎
  • 單進程多線程
  • MySQL 有走向封閉的趨勢
  • MariaDB 高度兼容 MySQL

安裝啓動

安裝

查看是否安裝MariaDB rpm包:
rpm -qa | grep MariaDB數據庫

在 CentOS 7.4 默認源中的 MariaDB 仍爲5.x版本,當須要 10.x 版本時,可經過添加第三方源實現:centos

MariaDB 官方源緩存

echo -e "[MariaDB]\nname = MariaDB\nbaseurl = http://yum.MariaDB.org/10.3/centos7-amd64\ngpgkey=https://yum.MariaDB.org/RPM-GPG-KEY-MariaDB\ngpgcheck=1" > /etc/yum.repos.d/MariaDB-10.3.repo

官方源比較慢的狀況,可使用清華鏡像源(根據須要執行yum clean all):安全

echo -e "[MariaDB]\nname = MariaDB\nbaseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.3.9/yum/centos/7.4/x86_64/\ngpgkey=https://yum.MariaDB.org/RPM-GPG-KEY-MariaDB\ngpgcheck=1" > /etc/yum.repos.d/MariaDB-10.3.repo

安裝MariaDB客戶端(包含MariaDB-common、MariaDB-client下載9MB 安裝50M):
yum install -y MariaDB.x86_64服務器

安裝MariaDB服務端(包含MariaDB-common、MariaDB-client、MariaDB-server):
yum install -y MariaDB-server.x86_64session

查看 MariaDB 安裝的文件:
rpm -ql MariaDB-serverrpm -ql MariaDB-client多線程

目錄文件 說明
/etc/my.cnf 默認配置文件
/var/lib/mysql/ 文件夾下是 MariaDB 數據庫目錄、錯誤日誌和 socket 文件
mysql mysql cli 客戶端
mysqldump 備份工具,基於 mysql協議 向 mysqld 發起查詢,將結果轉化爲insert語句導出。
mysqladmin 基於 mysql協議 管理 mysqld。
mysqlimport mysql 導入工具

注意:

  1. MariaDB 在 10.X 版本之前包名爲 mariadb,以後爲 MariaDB。但服務名仍爲 mariadb:service mariadb start;

啓動

啓動MariaDB服務:
service mariadb start

初始化(爲root設置密碼,刪除測試數據庫、匿名用戶):
/usr/bin/mysql_secure_installation

登陸mysql查看版本:
mysqladmin version -p123123

一鍵卸載MariaDB且清除MariaDB數據(便於調試):
yum -y remove `rpm -qa | grep MariaDB` && rm -rf /var/lib/mysql

權限

  1. 受權表:db、host、user、table_priv、column_priv、procs_priv
  2. 用戶帳號:'username'@'host' host:主機名、IP、通配符(%,_)
  3. 建立用戶:create user 'username'@'host' [identity by 'passwd']
  4. 查看用戶權限:show grants for 'username'@'host';
  5. 重命名用戶:RENAME USER oldname TO newname;
  6. 刪除用戶:DROP USER 'username'@'host';
  7. 修改密碼:SET PASSWORD

容許root遠程訪問:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123123' WITH GRANT OPTION;

  1. WITH GRANT OPTION 表示該用戶能夠將本身的權限受權給別人
  2. 若是隻授予部分權限,其中 all privileges 改成 select,insert,update,delete,create,drop,index,alter,grant,references,reload,shutdown,process,file 其中一部分。

精確到列的權限:

GRANT SELECT(Id,Name) ON testdb.Users TO testuser@'%' IDENTIFIED BY '123123'

重載受權表:
FLUSH PRIVILEGES;

忘記root密碼:

  1. systemctl stop mariadb.service
  2. mysqld_safe --skip-grant-tables
  3. mysql -u root
    1. update mysql.user set password=PASSWORD('newpassword') where User='root’;
    2. flush privileges;
  4. systemctl restart mariadb.service

事務

MySQL按照標準SQL定義了4種隔離級別,較低的隔離級別,能帶來更高的併發和更低的系統開銷。

  1. 未提交讀(READ-UNCOMMITTED)
    • 能夠讀到未提交的修改記錄
  2. 讀已提交(READ-COMMITTED)
    • 只要提交的修改記錄(包括其餘的事務)均可以讀到
    • 基於MVCC併發控制
  3. 可重複讀(REPEATABLE-READ)
    • 在事務開始第一次讀取後,其餘事務可修改讀到的數據,但讀到的數據不會被修改(幻讀狀況下會新增和減小)
    • 基於MVCC併發控制
  4. 串行讀(SERIALIZABLE)
    • 事務開始後發生對數據的操做(即便發生讀操做),其餘事務都不能修改數據
    • 基於鎖控制:實際上串行讀在RR級別上隱式加gap間隙共享鎖:select ... for update

備註:

  1. set tx_isolation='READ-UNCOMMITTED'; 調整當前 session 隔離級別
  2. select @@tx_isolation 查看當前 session 隔離級別
  3. show processlist; 查看 mysql 鏈接狀態

在4種隔離級別中又分別存在不一樣的讀問題:

  1. 髒讀(dirty reads)
    • 在 READ-UNCOMMITTED 級別會出現讀到未提交的數據
    T1:select * from users where id = 1;
    T2:insert into `users`(`id`, `name`) values (1, 'foo'); -- 事務未提交
    T1:select * from users where id = 1; -- 會讀到
  2. 不可重複讀(non-repeatable reads)
    • 在 READ-COMMITTED 級別會出現前後讀取不一致的狀況(關注點:讀-讀)
    T1:select * from users where id = 2;
    T2:insert into `users`(`id`, `name`) values (2, 'foo');
    T2:commit;
    T1:select * from users where id = 2; -- 會讀到
  3. 幻讀(phantom reads)
    • 在 REPEATABLE-READ 級別會出現插入事先不存在的記錄時,發現(insert會隱式的select)這些數據又存在(關注點:讀-寫)
    T1:select * from users where id = 3; -- 判斷是否有 Id = 3 的數據,沒有則插入
    T2:insert into `users`(`id`, `name`) values (3, 'bar'); -- 執行成功
    T1:insert into `users`(`id`, `name`) values (3, 'bar'); -- 執行失敗,因爲 T1 發生幻讀,不能支持該業務執行
  4. 鎖讀(lock reads)
    • 在 SERIALIZABLE 級別會出現讀的數據沒法修改狀況
    T1:select * from users where id = 3;
    T2:update `users` set `name` = 'baz' where `id` = 3; -- 執行失敗,因爲 Id = 3 的數據被鎖

    注意:

  5. 在同1次鏈接上,上次事務未提交,執行 start transaction;。會自動提交該鏈接上次的修改。

MVCC機制:

在 MVCC 以前,RC 和 RR 隔離級別是怎麼工做?

在 MVCC 以前,是單純依賴鎖的機制實現隔離級別。
當T1修改1條數據時加上排他鎖,T2事務的讀操做會被阻塞。當T1提交或回滾,鎖被釋放時,才能讀取到提交的數據。但通常應用都是讀多寫少,致使系統處於大量的等待中,很是低效。

有了 MVCC 機制後,效果是怎麼樣?

有了 MVCC 後,當數據被修改時,會生成1個副本出來供其餘事務讀取。不會出現阻塞狀況,讀的性能會大幅提高。只有 SERIALIZABLE 級別的讀操做纔有可能被阻塞。(MVCC應用在RC和RR隔離級別上)

MVCC 具體如何實現的?

  • 在 MySQL 中 MVCC 是在 InnoDB 存儲引擎上實現的。
  • InnoDB 爲每行數據增長3個字段:隱藏的ID、當前事務ID、回滾指針。
  • MVCC 依賴 undo log 和 readview 來肯定數據的可見性。

undo log:記錄了原始數據的多個副本,用來回滾和提供其餘事務讀取
readview:記錄了活動事務Id,用來肯定可見哪一個副本

  1. 在每一個事務開啓執行第1條語句的時候,會建立1個readview。
  2. 將行數據的當前事務TRID 與 readview中的事務RVID 比較
    1. TRID < 全部的 RVID:可見(以前的事務建立)
    2. TRID > 全部的 RVID:不可見(新事務建立)
    3. TRID 在 RVID 中存在:不可見(活動的事務建立)
    4. TRID 在 RVID 中不存在:可見(內存中commit或本身建立)
    5. 當數據不可見時,會從數據的回滾指針獲取數據從新判斷一遍
  3. RC 和 RR的區別:
    1. RR 在事務開始只建立1次 readview
    2. RC 在事務每次執行語句都會建立 readview

事務提交過程及日誌變化:

  1. 用 排他鎖 鎖定該行
  2. 記錄 redo buffer
  3. copy 數據到 undo buffer
  4. 內存中修改數據 填寫隱藏字段 事務Id 和 回滾指針

commit:

  1. redo log 文件持久化(innodb_flush_log_at_trx_commit)
  2. bin log 文件持久化(sync_binlog)(這一步完成能確保故障恢復)
  3. innodb引擎 commit(數據持久化,undo log)

注意:

  1. redo log 文件並不必定在commit時才作持久化
    1. Master Thread 每秒執行一次
    2. 每一個事務提交時
    3. 當重作日誌緩存可用空間 少於一半時
  2. redo log 是連續的一段存儲空間,而修改的數據極可能是隨機的區域
  3. undo log 並不是在事務提交完當即釋放
    1. 提交後放入待清理區域,由purge線程判斷是否仍有其餘事務在使用,來決定是否刪除。
    2. 默認undo log 存儲在 idb 表空間中,在 MariaDB 10.0(MySQL 5.7)後經過innodb_undo_directory 、innodb_undo_logs 、innodb_undo_tablespaces 可配置獨立文件

主從複製

主從複製能提供水平擴展 數據備份 數據分析 高可用性等,故開啓主從複製愈來愈必要。

複製

MariaDB 主從複製工做3步:

  1. 主庫的數據更改記錄到 binlog 中
  2. 從庫將主庫的日誌 複製到 relaylog 中
    1. 從庫使用 IO 線程請求主庫
    2. 主庫使用 dump 線程讀取 binlog 傳給
  3. 備庫 SQL 線程讀取 relaylog 事件,重放到數據庫。

配置複製:

  1. 在主庫和從庫建立複製帳號
    1. GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO repl@'10.0.0.%' IDENTIFIED BY 'p4ssword';
  2. 配置主庫和從庫
    1. 配置主服務器:

      [mysqld]
      log_bin   = mysql-bin
      server_id = 1 # 惟一,能夠用IP地址的末幾位
    2. 從服務器:

      [mysqld]
      log_bin   = mysql-bin
      server_id = 2
      log_slave_updates = 1 # 重放同時寫到binlog
      relay_log = /var/lib/mysql/mysql-relay-bin
  3. 從庫啓動複製
    1. MariaDB > CHANGE MASTER TO MASTER_HOST='server1', -> MASTER_USER='repl', -> MASTER_PASSWORD='p4ssword', -> MASTER_LOG_FILE='mysql-bin.000001', -> MASTER_LOG_POS=0;
    2. MariaDB > START SLAVE;
    3. MariaDB > SHOW SLAVE STATUS\G

注意:

  1. 要填寫的複製的POSITION,能夠經過 SHOW MASTER STATUS\G 查看
  2. 啓用複製功能不會給服務器太多的開銷。(主要是開啓 binlog 和 sync_binlog=1 fsync的開銷)
  3. 若是複製配置有問題,能夠重置配置信息:stop slave; reset slave;

半同步複製:

默認複製是單向異步的,也支持半同步複製功能(MariaDB 10.3 後內置不須要單獨安裝插件)。

  1. 主庫:
    set global rpl_semi_sync_master_enabled = 1;
    set global rpl_semi_sync_master_wait_point = AFTER_SYNC;
  2. 從庫:
    set global rpl_semi_sync_slave_enabled = 1;

semi配置:

配置項|推薦配置值|說明
rpl_semi_sync_master_enabled|ON|開啓主庫半同步複製
rpl_semi_sync_master_timeout|10000|最多等待從庫響應10s
rpl_semi_sync_master_wait_no_slave|ON|當沒有從節點時(從節點忽然斷開)是否繼續等待
rpl_semi_sync_master_wait_point|AFTER_SYNC|控制Wait Slave ACK的時機
rpl_semi_sync_slave_enabled|ON|開啓從庫半同步複製

原理:

  1. 半同步複製是在事務提交時,等待至少1個從庫接收並寫到relay log才返回給客戶端(Wait Slave ACK)。
  2. 半同步複製提升數據安全性,但也形成必定的延遲(最少是1次tcp/ip返還的時間)。
  3. 半同步複製默認AFTER_COMMIT是在bin log持久化及存儲引擎提交後再等待從庫接收寫到relay log,經過rpl_semi_sync_master_wait_point配置爲AFTER_SYNC,能夠將從庫複製操做改到主庫存儲引擎提交以前。

至關於有異步複製、半同步複製還有個全同步複製,表明爲 mysql-cluster性能太差,須要等待全部slave都同步才commit成功(性能太差)

注意:

  1. 半同步複製數據一致性並不能100%保證,在很是極端狀況下,AFTER_SYNC會出現從庫數據多的狀況,AFTER_COMMIT會出現從庫數據丟失的狀況。
  2. AFTER_SYNC 可讓存儲引擎commit支持group commit。因此性能安全性都比AFTER_COMMIT好

GTID

從MariaDB 10.0.2開始,GTID會自動啓用,在 binlog 中的每一個事件組(事務)都會先記錄1個GTID。

全局事務ID(簡稱GTID)由三個用短劃線「 - 」分隔的數字組成。例如:0-1-10

  1. 第一個數字0是域ID,它特定於全局事務ID(如下更多內容)。它是一個32位無符號整數。
  2. 第二個數字是服務器ID,與舊式複製中使用的相同。它是一個32位無符號整數。
  3. 第三個數字是序列號。這是一個64位無符號整數,對於登陸到binlog中的每一個新事件組,它會單調遞增。

爲何要使用GTID:

  1. 之前複製須要肯定 binlog 文件名+偏移量。使用GTID則會自動肯定。
  2. 之前經過 relaylog 文件記錄複製進度,且和數據同步是獨立進行。使用GTID,將會在數據更新的事務中一塊兒更新狀態(存在mysql.gtid_slave_pos)
  3. 更適合MHA時failover。

如何配置:

CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no }

  1. current_pos:當前服務器最後1條binlog命令的gtid記錄
  2. slave_pos:當前(從)服務器最後1次執行重放數據的gtid記錄

完整:CHANGE MASTER TO master_host = "127.0.0.1", master_user = "root", master_use_gtid = current_pos;

select @@gtid_slave_pos 可查看slave最後1個gtid。
select @@gtid_current_pos 可查看當前服務器執行的最後1個gtid。

注意:

  1. MariaDB和MySQL具備不一樣的GTID實現,而且它們彼此不兼容。
  2. 完成複製的必要條件主庫開啓 binlog 日誌,至關於開啓主庫的GTID。從庫及時不開啓 binlog, slave_pos 也會更新,但自執行的SQL不會影響current_pos。
  3. SET GLOBAL gtid_slave_pos = ""; 會重置GTID進度。

Galera集羣

在MariaDB 5.5和MariaDB 10.0中,MariaDB Galera Server是一個獨立的軟件包,而不是標準的MariaDB Server軟件包。從MariaDB 10.1開始,MariaDB Server和MariaDB Galera Server軟件包已經合併,而且在安裝MariaDB時會自動安裝Galera軟件包及其依賴項。Galera部件在配置以前保持休眠狀態,如插件或存儲引擎。

相比於複製、半同步複製,Galera集羣至關因而同步複製。其實現原理徹底與 binlog 沒有任何關係。

配置步驟:

  1. 配置
    ini [galera] # Mandatory settings wsrep_on=ON # rpm -ql galera.x86_64 -> /usr/lib64/galera/libgalera_smm.so wsrep_provider=/usr/lib64/galera/libgalera_smm.so # DNS名稱也有效,IP是性能的首選 wsrep_cluster_address="gcomm://172.17.145.110, 172.18.0.2" binlog_format=row default_storage_engine=InnoDB innodb_autoinc_lock_mode=2
  2. 引導新集羣
    $ galera_new_cluster(Systemd推薦)
  3. 在多臺服務器上開啓mysql服務
    $ service mariadb start

注意:

  1. Galera Cluster方式會出現自增ID不連續的狀況,可以使用GUID由程序生成

配置

命令 說明
mysqld --verbose --help | less 查看默認配置及配置說明
cat /etc/my.cnf | grep -v '^#' | grep -v '^$' 查看去除註釋後的配置文件
show [global] variables; 查看配置
set [global] name=value; 修改配置
配置項 默認值 推薦值 說明
autocommit on off 是否開啓自動提交,默認開啓,全部修改操做都會自動開啓1個事務,並提交。(影響性能)
skip-name-resolve false true 跳過IP反解爲域名過程,默認關閉,全部鏈接都會反解IP爲域名。(影響性能以及受權)
innodb_flush_log_at_trx_commit 1 1 在事務提交時確保redolog持久化
innodb-file-per-table true true 獨立表空間,每1個表都以獨立文件存儲
sync_binlog 0 1 在事務提交時確保binlog持久化

(配置項會不斷更新比較重要的)

監控

監控可以使用 Zabbix 對MariaDB 作監控。

Zabbix

(實現原理是經過查詢 MariaDB 的狀態變量實現)

本文地址:https://www.cnblogs.com/neverc/p/9870088.html

相關文章
相關標籤/搜索