MySQL深刻學習(三)--存儲引擎、事務、日誌、備份、主從複製

MySQL

1、存儲引擎

1.簡介

​ MySQL中的數據用各類不一樣的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不一樣的存儲機制、索引技巧、鎖定水平而且最終提供普遍的不一樣的功能和能力。經過選擇不一樣的技術,你可以得到額外的速度或者功能,從而改善你的應用的總體功能。
​ 例如,若是你在研究大量的臨時數據,你也許須要使用內存MySQL存儲引擎。內存存儲引擎可以在內存中存儲全部的表格數據。又或者,你也許須要一個支持事務處理的數據庫(以確保事務處理不成功時數據的回退能力)。
​ 這些不一樣的技術以及配套的相關功能在 MySQL中被稱做存儲引擎(也稱做表類型)。mysql

2.分類

MySQL兩種存儲引擎:redis

  • MyISAM
MySQL的默認數據庫引擎(5.5版以前),由早期的ISAM(Indexed Sequential Access Method:有索引的順序訪問方法)所改良。雖然性能極佳,但卻有一個缺點:不支持事務處理(transaction)。不過,在這幾年的發展下,MySQL也導入了InnoDB(另外一種數據庫引擎),以強化參考完整性與併發違規處理機制,後來就逐漸取代MyISAM。
  • InnoDB
InnoDB,是MySQL的數據庫引擎之一,爲MySQL AB發佈binary的標準之一。InnoDB由Innobase Oy公司所開發,2006年五月時由甲骨文公司併購。
    與傳統的ISAM與MyISAM相比,InnoDB的最大特點就是支持了ACID兼容的事務(Transaction)功能,相似於PostgreSQL。目前InnoDB採用雙軌制受權,一是GPL受權,另外一是專有軟件受權。
# 使用MySQL客戶端命令,顯示當前MySQL系統所支持的數據庫引擎。
show engines;

# 看你的mysql當前默認的存儲引擎:
mysql> show variables like '%storage_engine%';
 
# 你要看某個表用了什麼引擎(在顯示結果裏參數engine後面的就表示該表當前用的存儲引擎):
mysql> show create table 表名;

3.MyISAM

​ MyISAM不支持事務,不支持外鍵,支持全文索引,處理速度快。主要面向OLAP數據庫應用。sql

​ MyISAM存儲引擎的表存儲成3個文件,文件名與表名相同,擴展名分別爲:frm,MYD,MYI。數據庫

  • frm文件:存儲表的結構。
  • myd文件:存儲數據。
  • myi文件:存儲存儲索引。

4.InnoDB

InnoDB是一個健壯的事務型存儲引擎,這種存儲引擎已經被不少互聯網公司使用,爲用戶操做很是大的數據存儲提供了一個強大的解決方案。InnoDB還引入了行級鎖定和外鍵約束,在如下場合下,使用InnoDB是最理想的選擇:vim

  1. 更新密集的表。InnoDB存儲引擎特別適合處理多重併發的更新請求。
  2. 事務。InnoDB存儲引擎是支持事務的標準MySQL存儲引擎。
  3. 自動災難恢復。與其它存儲引擎不一樣,InnoDB表可以自動從災難中恢復。
  4. 外鍵約束。MySQL支持外鍵的存儲引擎只有InnoDB。
  5. 支持自動增長列AUTO_INCREMENT屬性。

InnoDB存儲引擎的表存儲成2個文件安全

  • frm文件:存儲表的結構。
  • ibd文件:存儲表的數據行和索引

2、事務

1.簡介

MySQL 事務主要用於處理操做量大,複雜度高的數據。好比說,在人員管理系統中,你刪除一我的員,你即須要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操做語句就構成一個事務!併發

  • 在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
  • 事務處理能夠用來維護數據庫的完整性,保證成批的 SQL 語句要麼所有執行,要麼所有不執行。
  • 事務用來管理 insert,update,delete 語句

通常來講,事務是必須知足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。運維

  • 原子性:一個事務(transaction)中的全部操做,要麼所有完成,要麼所有不完成,不會結束在中間某個環節。事務在執行過程當中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。
  • 一致性:在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。這表示寫入的資料必須徹底符合全部的預設規則,這包含資料的精確度、串聯性以及後續數據庫能夠自發性地完成預約的工做。
  • 隔離性:數據庫容許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。事務隔離分爲不一樣級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
  • 持久性:事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。

2.事務的併發問題

  一、髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據異步

  二、不可重複讀:事務 A 屢次讀取同一數據,事務 B 在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果 不一致。

  三、幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。

  小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住知足條件的行,解決幻讀須要鎖表

3.MySQL事務隔離級別

事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommitted)
不可重複讀(read-committed)
可重複讀(repeatable-read)
串行化(serializable)

注: mysql默認的事務隔離級別爲repeatable-read

4.使用

# 開始一個事務
BEGIN 
# 增刪改操做
。。。。
。。。。
# 事務回滾
ROLLBACK 

# 事務確認,一旦提交,纔會應用到數據庫,沒提交以前的數據變化都是虛假的
COMMIT 


# 隱式提交,也就是自動提交
# 查看autocommit,on/off
show variables like 'auto%'
# autocommitm默認爲1,每次執行sql語句都會自動提交

# 若是須要事務操做的話
# 臨時禁止自動提交
SET AUTOCOMMIT=0 
# 永久的話,去配置文件my.cnf ,加上一句話
autocommit=0;
# 舉例

# 1.BEGIN以後沒有提交或回滾,又開始BEGIN,會致使上面的的自動提交
BEGIN 
。。。。
。。。。
BEGIN
。。。。


# 2.create drop alter  grant 也會觸發數據提交
BEGIN 
。。。。
。。。。
create drop alter  grant

3、日誌

1. 錯誤日誌

​ 錯誤日誌是一個文本文件。
錯誤日誌記錄了MySQL Server每次啓動和關閉的詳細信息以及運行過程當中全部較爲嚴重的警告和錯誤信息。
能夠用--log-error[=file_name]選項來開啓mysql錯誤日誌,該選項指定mysqld保存錯誤日誌文件的位置。

# my.cnf配置文件
log_error=/var/log/mysql.log


#查看當前的錯誤日誌配置,缺省狀況下位於數據目錄
mysql> show variables like 'log_error';

2.事務日誌(十六進制的變化)

innodb事務日誌包括redo.log和undo.log。

  • redo.log是重作日誌,提供前滾操做。
  • undo.log是回滾日誌,提供回滾操做。

undo.log不是redo.log的逆向過程,其實它們都算是用來恢復的日誌:

  1. redo log一般是物理日誌,記錄的是數據頁的物理修改,而不是某一行或某幾行修改爲怎樣怎樣,它用來恢復提交後的物理數據頁(恢復數據頁,且只能恢復到最後一次提交的位置)。
  2. undo用來回滾行記錄到某個版本。undo log通常是邏輯日誌,根據每行記錄進行記錄。

2.二進制日誌 (binlog,邏輯型日誌)

做用

  • 記錄全部變動類的語句

    ​ DDL,DCL :以語句方式(statement)記錄

    ​ DML(已提交的事務語句):默認是以行模式記錄(row模式,數據行的變化)

  • 能夠作數據恢復和操做的審計

操做

# 二進制日誌默認不開啓
# 須要配置到my.cnf配置文件
log_bin=/opt/mysql/data/mysql-bin
binlog_format=row  # 日誌格式 row格式能夠避免MYSQL複製中出現主從不一致的問題,官方推薦這種格式。
server_id=6
sync_binlog=1  



# 查看日誌信息
mysql> show binary logs;
mysql> show master status;


# 查看日誌內容
# 按事件查看日誌內容
mysql> show binlog events in 'mysql-bin.000012';
# 直接查看日誌內容
mysql> mysqlbinlog --base64-output=decode-rows -vvv /opt/mysql/data/mysql-bin.000012 |more



# 截取二進制日誌
# --start-position=219  起始位置
# --stop-position=186613 結束位置
# /opt/mysql/data/mysql-bin.000012  截取的日誌
# >/tmp/binlog.sql  存放到sql文件
mysqlbinlog --start-position=219 --stop-position=186613 /opt/mysql/data/mysql-bin.000012 >/tmp/binlog.sql

3.慢日誌

​ MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,經過慢查詢日誌,咱們能夠知道是那些語句的效率慢,能夠去語句調優

# 配置my.cnf
slow_query_log=1 # 開啓慢日誌
slow_query_log_file=/opt/mysql/data/standby-slow.log # 存儲位置
long_query_time=1   # 超過1秒會存入慢日誌,默認是10秒
log_queries_not_using_indexes=1  # 不走索引的也認爲是慢語句,默認關閉

# 使用Box Anemometer基於pt-query-digest將MySQL慢查詢可視化

4、備份

1.分類

  • 邏輯備份:SQL語句的備份
  • 物理備份:數據頁備份

2.邏輯備份工具

# MySQL和redis之間如何順滑的遷移數據
# 先把數據存到redis認識的文件,redis再從該文件讀取
select xxxx from 表名  into outfile '/tmp/redis.txt'
# 備份命令mysqldump格式
mysqldump -h主機名  -P端口 -u用戶名 -p密碼 –database 數據庫名 > 文件名.sql 

# -h本地能夠省略
# -P默認3306也能夠省略
# –database 指定數據庫。若是有庫名,–database能夠省略;若是備份當前所在庫,庫名也能夠省略


# -A 全庫備份
mysqldump -uroot -p123 -A >/backup/full.sql

# -B 備份一個或多個指定庫,會備份建庫語句
# 不加-B也能夠備份單庫,可是卻沒有建庫語句的
mysqldump -uroot -p123 -B world bbs  >/backup/wb.sql


# 備份單庫中的表
# world庫中的city表、country表
mysqldump -uroot -p123  world city country  >/backup/ccc.sql


# 其餘參數,必寫
--master-data=2       # 備份時記錄二進制日誌的狀態
--single-transaction  # 開啓innodb熱備功能
-R 
--triggers


# 完整的備份語句
mysqldump -uroot -p123 -A --master-data=2 --single-transaction  -R   --triggers  >/backup/full.sql


# 還原MySQL數據庫的命令

mysql -h主機名  -P端口 -u用戶名 -p密碼 –database 數據庫名 < 文件名.sql

5、主從複製

1.簡介

​ Mysql做爲目前世界上使用最普遍的免費數據庫,相信全部從事系統運維的工程師都必定接觸過。但在實際的生產環境中,由單臺Mysql做爲獨立的數據庫是徹底不能知足實際需求的,好比數據庫損壞,可使用備份來恢復,可是效率不高,相比之下主從複製效率高、安全性更高

​ 所以,通常來講都是經過 主從複製(Master-Slave)的方式來同步數據,再經過讀寫分離(MySQL-Proxy)來提高數據庫的併發負載能力 這樣的方案來進行部署與實施的。

2.原理

​ MySQL的主從複製是一個異步的複製過程,數據庫從一個Master複製到Slave數據庫,在Master與Slave之間實現整個主從複製的過程是由三個線程參與完成的,其中有兩個線程(SQL線程和IO線程)在Slave端,另外一個線程(IO線程)在Master端。

流程說明:

MySQL主從複製以前咱們須要先啓動Master數據庫而後再啓動Salve數據庫,而後在Salve數據庫中執行start slave;,執行完成以後,流程就以下了:

  1. Salve的IO線程會讀取mastr.info文件中配置好的主庫信息,好比說存放的有:Master數據庫的用戶名、密碼、端口、還有Master的binlog索引位置;
  2. 拿到信息以後就帶着信息去連接Master的主庫IO線程
  3. 當主庫的IO線程先檢查SLave傳過來的配置信息是否正確,若是正確,就拿着Slave傳過來的binlog索引位置和Master庫的binlog文件中最後一個索引位置進行對比,若是一致就陷入等待狀態,等待Master的binlog索引位置更新;
  4. 若是不一致就把Slave傳過來的binlog索引位置日後的全部SQL語句包括最後一條SQL語句的索引位置發送個給Slave的IO線程;
  5. Slave的IO線程拿到信息以後,先把Master傳過來的binlog索引在Slave的master.info文件中進行更新;
  6. 而後再把Master傳過來的SQL語句寫入到relay文件中,而後繼續循環執行第二個步驟;
  7. Slave的SQL線程會一直持續的觀察relay日誌文件中是否有改動,若是沒有就繼續監聽;
  8. 若是發現relay中有變更,那麼就獲取變更的內容轉換爲SQL語句,而且把SQL語句在Salve的數據庫中進行執行

3.實現主從複製

master機配置

Master   slave  
 3307---->3308    

# 1.因爲,主從複製基於二進制日誌,因此主庫要開啓二進制日誌,修改配置並重啓服務
vim /data/3307/my.cnf 
log_bin=/data/3307/mysql-bin
systemctl restart mysqld3307

# 2.Master中建立複製用戶
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

# 3.測試是否建立成功
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

slave機配置

# 1.再salve機配置對應master機的信息
mysql> CHANGE MASTER TO
  MASTER_HOST='10.0.0.200', # master機IP
  MASTER_USER='repl',       # master機MySQL用戶名
  MASTER_PASSWORD='123',    # mysql密碼
  MASTER_PORT=3307,         # master機端口
  MASTER_LOG_FILE='mysql-bin.000001',# 二進制日誌的起始文件
  MASTER_LOG_POS=154;       # 二進制日誌的起始位置


# 2.啓動salve機服務
start slave;


# 3.測試salve機是否啓動
show slave status\G

# 啓動成功應當現實配置
。。。。。。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
。。。。。。
相關文章
相關標籤/搜索