牛皮了!7000字MySQL學習筆記,從入到放棄

牛皮了!7000字MySQL學習筆記,從入到放棄

 

MySQL數據庫簡介

MySQL近兩年一直穩居第二,隨時有可能超過Oracle計晉升爲第一名,因爲MySQL的性能一直在被優化,同時安全機制也是逐漸成熟,更重要的是開源免費的。

MySQL是一種關係數據庫管理系統,關係數據庫將數據保存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。

MySQL所使用的 SQL 語言是用於訪問數據庫的最常用標準化語言。MySQL 軟件採用了雙授權政策,分爲社區版和商業版,由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作爲網站數據庫。

MySQL InnoDB存儲引擎

  • 存儲引擎InnoDB是目前MySQL版本默認的存儲引擎,也是MySQL推薦使用的存儲引擎,是集高可靠性和高性能於一身的存儲引擎。
  • 在MySQL5.7版本中,除非在配置文件中顯示指定default storage engine或者創建表時顯示使用engine=語句指定其它的存儲引擎,否則默認都是InnoDB。

InnoDB存儲引擎的優勢:

  • DML語句支持事務功能,保證ACID特性
  • 性能鎖的使用保證了高併發的屬性
  • InnoDB對有主鍵的表會依據主鍵優化查詢性能,也稱聚簇索引,將所有數據存儲在聚簇索引上以減少對主鍵查詢的IO消耗
  • 爲保證數據的一致性,InnoDB還支持外鍵屬性,確保有外鍵約束的表之間不會有不一致的數據
  • 當服務器硬件或者軟件故障導致MySQL重啓後,InnoDB會自動識別已經在故障之前提交的數據,並回退所有故障時未提交的數據,最大限度的保護數據不會丟失(crash recovery)

1、事物(Transaction)
2、MVCC(多版本併發控制)
3、行級鎖(Row-level Lock)
4、支持外鍵
5、ACSR(Auto Crrash safe Recovery)自動的故障安全恢復
6、支持熱備份

MySQL複製集羣原理與實戰

MySQL複製有兩種方法:

  • 傳統方式:基於主庫的bin-log將日誌事件和事件位置複製到從庫,從庫再加以 應用來達到主從同步的目的。
  • Gtid方式:global transaction identifiers是基於事務來複制數據,因此也就不 依賴日誌文件位置,同時又能更好的保證主從庫數據一致性。

數據備份多種方式:

  • 物理備份是指通過拷貝數據庫文件的方式完成備份,這種備份方式適用於數據庫很大,數據重要且需要快速恢復的數據庫
  • 邏輯備份是指通過備份數據庫的邏輯結構(create database/table語句)和數據內容(insert語句或者文本文件)的方式完成備份。這種備份方式適用於數據庫不是很大,或者你需要對導出的文件做一定的修改,又或者是希望在另外的不同類型服務器上重新建立此數據庫的情況
  • 通常情況下物理備份的速度要快於邏輯備份,另外物理備份的備份和恢復粒度範圍爲整個數據庫或者是單個文件。對單表是否有恢復能力取決於存儲引擎,比如在MyISAM存儲引擎下每個表對應了獨立的文件,可以單獨恢復;但對於InnoDB存儲引擎表來說,可能每個表示對應了獨立的文件,也可能表使用了共享數據文件
  • 物理備份通常要求在數據庫關閉的情況下執行,但如果是在數據庫運行情況下執行,則要求備份期間數據庫不能修改
  • 邏輯備份的速度要慢於物理備份,是因爲邏輯備份需要訪問數據庫並將內容轉化成邏輯備份需要的格式;通常輸出的備份文件大小也要比物理備份大;另外邏輯備份也不包含數據庫的配置文件和日誌文件內容;備份和恢復的粒度可以是所有數據庫,也可以是單個數據庫,也可以是單個表;邏輯備份需要在數據庫運行的狀態下執行;它的執行工具可以是mysqldump或者是select … into outfile兩種方式

MySQL複製有多種類型:

  • 異步複製:一個主庫,一個或多個從庫,數據異步同步到從庫。
  • 同步複製:在MySQL Cluster中特有的複製方式。
  • 半同步複製:在異步複製的基礎上,確保任何一個主庫上的事務在提交之前至 少有一個從庫已經收到該事務並日志記錄下來。
  • 延遲複製:在異步複製的基礎上,人爲設定主庫和從庫的數據同步延遲時間, 即保證數據延遲至少是這個參數。

MySQL高可用架構設計與實戰

MHA

MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點。

  • MHA Manager: 可以單獨部署在一臺獨立的機器上管理多個master-slave集羣,也可以部署在一臺slave節點上。
  • MHA Node: 行在每臺MySQL服務器上。
  • MHA Manager會定時探測集羣中的master節點,當master出現故障時,它可以自動將最新數據的slave提升爲新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程序完全透明。

MGR

  • Mysql Group Replication(MGR)是從5.7.17版本開始發佈的一個全新的高可用和高擴張的MySQL集羣服務。
  • 高一致性,基於原生複製及paxos協議的組複製技術,以插件方式提供一致數據安全保證;
  • 高容錯性,大多數服務正常就可繼續工作,自動不同節點檢測資源徵用衝突,按順序優先處理,內置動防腦裂機制;
  • 高擴展性,自動添加移除節點,並更新組信息;
  • 高靈活性,單主模式和多主模式。單主模式自動選主,所有更新操作在主進行;多主模式,所有server同時更新。

MySQL性能優化

MySQL索引原理:

  • 顧名思義,B-tree索引使用B-tree的數據結構存儲數據,不同的存儲引擎以不同的方式使用B-Tree索引,比如MyISAM使用前綴壓縮技術使得索引空間更小,而InnoDB則按照原數據格式存儲,且MyISAM索引在索引中記錄了對應數據的物理位置,而InnoDB則在索引中記錄了對應的主鍵數值。B-Tree通常意味着所有的值都是按順序存儲,並且每個葉的葉到根的距離相同。
  • B-Tree索引驅使存儲引擎不再通過全表掃描獲取數據,而是從索引的根節點開始查找,在根節點和中間節點都存放了指向下層節點的指針,通過比較節點頁的值和要查找值可以找到合適的指針進入下層子節點,直到最下層的葉子節點,最終的結果就是要麼找到對應的值,要麼找不到對應的值。整個B-tree樹的深度和表的大小直接相關。
  • 全鍵值匹配:和索引中的所有列都進行匹配,比如查找姓名爲zhang san,出生於1982-1-1的人
  • 匹配最左前綴:和索引中的最左邊的列進行匹配,比如查找所有名爲zhang的人
  • 匹配列前綴:匹配索引最左邊列的開頭部分,比如查找所有以z開頭的姓名的人
  • 匹配範圍值:匹配索引列的範圍區域值,比如查找姓在li和wang之間的人
  • 精確匹配左邊列並範圍匹配右邊的列:比如查找所有姓爲Zhang,且名字以K開頭的人
  • 只訪問索引的查詢:查詢結果完全可以通過索引獲得,也叫做覆蓋索引,比如查找所有名爲zhang的人的姓名

MySQL表分區介紹:

  • 可以允許在⼀個表⾥存儲更多的數據,突破磁盤限制或者⽂件系統限制。
  • 對於從表⾥將過期或歷史的數據移除在表分區很容易實現,只要將對應的分區移除即可。
  • 對某些查詢和修改語句來說,可以⾃動將數據範圍縮⼩到⼀個或⼏個表分區上,優化語句執⾏效率。⽽且可以通過顯示指定表分區來執⾏語句,⽐如 select * from temp partition(p1,p2) where store_id < 5;
  • 表分區是將⼀個表的數據按照⼀定的規則⽔平劃分爲不同的邏輯塊,並分別進⾏物理存儲,這個規則就叫做分區函數,可以有不同的分區規則。
  • MySQL5.7版本可以通過show plugins語句查看當前MySQL是否⽀持表分區功能。
  • MySQL8.0版本移除了show plugins⾥對partition的顯示,但社區版本的表分區功能是默認開啓的。
  • 但當表中含有主鍵或唯⼀鍵時,則每個被⽤作分區函數的字段必須是表中唯⼀鍵和主鍵的全部或⼀部分,否則就⽆法創建分區表。

MySQL分庫分表

  • 能不分就不分,1000萬以內的表,不建議分片,通過合適的索引,讀寫分離等方式,可以很好的解決性能問題。
  • 分片數量儘量少,分片儘量均勻分佈在多個DataHost上,因爲一個查詢SQL跨分片越多,則總體性能越差,雖然要好於所有數據在一個分片的結果,只在必要的時候進 行擴容,增加分片數量。
  • 分片規則需要慎重選擇,分片規則的選擇,需要考慮數據的增長模式,數據的訪 問模式,分片關聯性問題,以及分片擴容問題,最近的分片策略爲範圍分片,枚舉分片, 一致性Hash分片,這幾種分片都有利於擴容。
  • 儘量不要在一個事務中的SQL跨越多個分片,分佈式事務一直是個不好處理的問題。
  • 查詢條件儘量優化,儘量避免Select * 的方式,大量數據結果集下,會消耗大量 帶寬和CPU資源,查詢儘量避免返回大量結果集,並且儘量爲頻繁使用的查詢語句建立索引。

MySQL數據庫讀寫分離高可用

海量數據的存儲和訪問成爲了系統設計的瓶頸問題,日益增長的業務數據,無疑對數據庫造成了相當大的負載,同時對於系統的穩定性和擴展性提出很高的要求。隨着時間和業務的發展,數據庫中的表會越來越多,表中的數據量也會越來越大,相應地,數據操作的開銷也會越來越大;另外,無論怎樣升級硬件資源,單臺服務器的資源(CPU、磁盤、內存、網絡IO、事務數、連接數)總是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。分表、分庫和讀寫分離可以有效地減小單臺數據庫的壓力。

MySQL性能監控

MySQL性能監控的指標大體可以分爲以下4大類:

  • 查詢吞吐量
  • 查詢延遲與錯誤
  • 客戶端連接與錯誤
  • 緩衝池利用率

對於MySQL性能監控,官方也提供了相關的服務插件:MySQL-Percona,下面簡單介紹一下插件的安裝

[root@db01 ~]# yum -y install php php-mysql
[root@db01 ~]# wget https://www.percona.com/downloads/percona-monitoring-plugins/percona-monitoring-plugins-1.1.8/binary/redhat/7/x86_64/percona-zabbix-templates-1.1.8-1.noarch.rpm
[root@db01 ~]# rpm -ivh percona-zabbix-templates-1.1.8-1.noarch.rpm
warning: percona-zabbix-templates-1.1.8-1.noarch.rpm: Header V4 DSA/SHA1 Signature, key ID cd2efd2a: NOKEY
Preparing... ################################# [100%]
Updating / installing...
   1:percona-zabbix-templates-1.1.8-1 ################################# [100%]

Scripts are installed to /var/lib/zabbix/percona/scripts
Templates are installed to /var/lib/zabbix/percona/templates

最後,可以配合其它監控工具來實現對MySQL的性能監控。

MySQL服務器配置插件:

  • 修改php腳本連接MySQL的monitor@localhost用戶
  • 修改MySQL的sock文件路徑
[root@db01 ~]# sed -i '30c $mysql_user = "monitor";' /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php
[root@db01 ~]# sed -i '31c $mysql_pass = "123456";' /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php
[root@db01 ~]# sed -i '33c $mysql_socket = "/tmp/mysql.sock";' /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php

測試是否可用( 可以從MySQL中獲取到監控值 )

[root@db01 ~]# /usr/bin/php -q /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php --host localhost --items gg
gg:12

# 確保當前文件的 屬主 屬組 是zabbix,否則zabbix監控取值錯誤。
[root@db01 ~]# ll -sh /tmp/localhost-mysql_cacti_stats.txt
4.0K -rw-rw-r-- 1 zabbix zabbix 1.3K Dec 5 17:34 /tmp/localhost-mysql_cacti_stats.txt

移動zabbix-agent配置文件到 /etc/zabbix/zabbix_agentd.d/目錄

[root@db01 ~]# mv /var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf /etc/zabbix/zabbix_agentd.d/
[root@db01 ~]# systemctl restart zabbix-agent.service

導入並配置Zabbix模板與主機:

默認模板監控時間爲 5分鐘 ( 當前測試修改爲 30s) 同時也要修改Zabbix模板時間

# 如果要修改監控獲取值的時間不但要在zabbix面板修改取值時間,bash腳本也要修改。
[root@db01 scripts]# sed -n '/TIMEFLM/p' /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh
TIMEFLM=`stat -c %Y /tmp/$HOST-mysql_cacti_stats.txt`
if [ `expr $TIMENOW - $TIMEFLM` -gt 300 ]; then   
# 這個 300 代表 300s 同時也要修改。

默認模板版本爲 2.0.9,無法在4.0版本使用,可以先從3.0版本導出,然後再導入4.0版本 。

其實,在實際生產過程中,還是有相關的專業監控數據庫的第三方開源軟件的,LZ之前也寫過相關的文章

MySQL用戶行爲安全

  • 假設這麼一個情況,你是某公司mysql-DBA,某日突然公司數據庫中的所有被人給刪了。
  • 儘管有數據備份,但是因服務停止而造成的損失上千萬,現在公司需要查出那個做刪除操作的人。
  • 但是擁有數據庫操作權限的人很多,如何排查,證據又在哪?
  • 是不是覺得無能爲力?
  • mysql本身並沒有操作審計的功能,那是不是意味着遇到這種情況只能自認倒黴呢?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章