mysql

mysql


一、數據庫種類及關係型數據庫原理2

1.1數據庫種類:2

1.2非關係型數據庫種類3

1.3非關係型數據庫產品介紹4

二、mysql介紹及安裝5

2.1 mysql數據庫優勢6

2.2 mysql三條產品線:6

2.3 mysql選擇建議6

2.4 mysql5.1/5.5編譯安裝7

三、mysql應用管理9

3.1 mysql啓動與關閉原理9

3.2登陸mysql9

3.3修改mysql密碼10

3.4找回丟失的mysql密碼11

3.5 SQL語言11

3.6數據庫字符集12

3.7顯示-連接-刪除等數據庫的管理13

3.8 mysql建表語句及表結構15

3.9 mysql索引16

3.10 DML語句之insert19

3.11 DQL之select20

3.12 DQL之select多表連表查詢21

3.13 DML之update24

3.14 DML之alter24

四、mysql字符集25

4.1 數據庫字符集介紹25

4.2 mysql數據庫常見字符集介紹25

4.3 如何選擇合適的字符集?25

4.4 mysql插入中文數據不亂碼深度剖析26

4.5 數據字符集修改案例28

五、mysql備份/增量備份29

5.1 備份單個數據庫29

5.2 mysqldump邏輯備份工作原理30

5.3 備份多個庫30

5.4 多表備份30

5.5 只備份表結構及數據31

5.6 myisam與innodb引擎備份32

5.7 source恢復mysql數據32

5.8 分庫備份後mysql分庫恢復33

六、mysql進程狀態binlog33

6.1 mysql進程狀態33

6.2 mysqlbinlog33

6.3 mydqldump(--master-data)35

七、mysql主從複製35

7.1 mysql主從複製介紹35

7.2 mysql主從同步原理36

7.3 mysql主從同步部署36

7.4 mysql主從同步配置步驟39

7.5 mysql主從故障及主從延遲解決方案39

7.6 mysql主從常見故障41

7.7 mysql主從複製線程狀態42

7.8 mysql主從讀寫分離授權方案43

7.9 mysql雙主方案45

八、mysql服務多種日誌47

8.1 mysql三種常見日誌類型47

8.2 binlog日誌的三種模式47

8.3 調整binlog日誌模式方法48

九、mysql存儲引擎48

9.1什麼是存儲引擎48

9.2 mysql事務以及ACID特性48

9.3 MyISAM引擎特點及調優49

9.4 InnoDB引擎特點及調優50

9.5修改mysql引擎51

十、mysql優化52

10.1 mysql負載高情況查看52

10.2 mysql優化思路52

10.3 mysql數據庫優化52





一、數據庫種類及關係型數據庫原理

1.1數據庫種類:

按照早期的數據庫理論,比較流行的數據庫模型有三種:

層次式數據庫

網絡式數據庫

關係型數據庫


在當今互聯網中,最常用的數據庫模型:

關係型數據庫

非關係型數據庫


關係型數據庫使用類似於excel表格來表示

關係型數據庫使用結構化查詢語言SQL語句來對數據進行存取

代表作品,mysql oracle


隨着互聯網web2.0網站的興起,傳統的關係型數據庫在應付web2.0網站,特別是對於規模日益擴大的海量數據,超大規模和高併發的微博、微信、SNS類型的web2.0純動態網絡瓶頸都難以有效突破,於是開始出現了大批針對特定場景,以高性能和使用便利爲目的的功能特異化的數據庫產品,NoSQL(非關係型)類的數據庫就是在這樣的情境中誕生並得到了非常迅速的發展。


【動態請求越來越多,對數據庫的要求越來越高,傳統的數據庫遵循SAD理論(保持數據一致性,存放磁盤等)存取數據很慢,在這種情況下,非關係型數據庫就誕生了】

NoSQL:

Google的BigTable

Amazon的Dynamo

成功的商業NoSQL


開源NoSQL:

Facebook的Cassandra

Apache的HBase

Redis,mongodb


1.2非關係型數據庫種類

(1)鍵值(Key-Value)存儲數據庫

鍵值數據庫就類似傳統語言中使用的哈希表。可以通過key來添加、查詢或者刪除數據,因爲使用key主鍵訪問,所以會獲得很高的性能及擴展性。

鍵值(Key-Value)數據庫主要是使用一個哈希表,這個表中有一個特定的鍵和一個特向指定的數據。Key/Value模型對於IT系統來說的有時在於簡單、易部署、高併發。

典型產品:Memcached、Redis、MemcacheDB、Berkeley DB


(2)列存儲(Column-oriented)數據庫

列存儲數據庫將數據存儲在列族(column family)中,一個列族存儲經常被一起查詢的相關數據。舉個例子,如果我們有一個Person類,我們通常會一起查詢他們的姓名和年齡而不是薪資。這種情況下,姓名和年齡就會被放入一個列族中,而薪資則在另一個列族中。

這部分數據庫通常是用來應對分佈式存儲的海量數據。鍵仍然存在,但是它們的特點是指向了多個列。這些列是有列家族來安排的。

典型產品:Cassandra,HBase


(3)面向文檔(Document-Oriented)數據庫

文檔型數據庫的靈感是來自於Lotus Notes辦公軟件的,而且它同第一種鍵值存儲相似。該類型的數據模型是版本化的文檔,半結構化的文檔以特定的格式存儲,比如JSON。文檔型數據庫可以看作是鍵值數據庫的升級版,允許之間嵌套鍵值。而且文檔型數據庫比鍵值數據庫的查詢效率更高。

面向文檔數據庫會將數據以文檔的形式存儲。每個文檔都是自包含的數據單元,是一系列數據項的集合。每個數據項都有一個名稱與對應的值,值既可以是簡單的數據類型,如字符串、數字和日期等;也可以使複雜的類型,如有序列表和關聯對象。數據存儲的最小單位是文檔,同一個表中存儲的文檔屬性可以是不通的,數據可以使用XML、JSON或者JSONB等多種形式存儲。

典型產品:MogoDB、CouchDB


(4)圖形(Graph)數據庫

圖形數據庫允許我們將數據庫以圖的方式存儲。實體會被作爲頂點,而實體之間的關係則會被作爲邊。比如我們有三個實體,Steve Jobs、Apple和Next,則會有兩個"Founded by"的邊將Apple和Next連接到Steve Jobs.

圖形結構的數據庫同其他行列以及剛性結構的SQL數據庫不同,它是使用靈活的圖形模型,並且能夠擴展到多個服務器上。NoSQL數據庫沒有標準的查詢語言(SQL),因此進行數據庫查詢需要指定數據模型。許多NoSQL數據庫都有REST式的數據接口或者查詢API。

典型產品:Neo4J、InfoGrid


1.3非關係型數據庫產品介紹


(1)Memcached(key-value)

  Memcached是一個開源的、高性能的、具有分佈式內存對象的緩存系統。通過它可以減輕數據庫負載,加速動態Web應用,最初版本由LiveJournal的Brad Fitzpatrick在2003年開發完成。目前全球有非常多的用戶都在使用它來構建自己的大負載網站或提高自己的高訪問網站的響應速度。

注意:Memcache是這個項目的名稱,而Memcached是服務器端的主程序文件名。


(2)redis(key-value)

  和Memcached類似,redis也是一個key-value型存儲系統。但redis支持的存儲value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)等。這些數據類型都支持push/pop、add/remove及取交集、並集、差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不方式的排序。與memcached一樣,爲了保證效率,redis的數據都是緩存在內存中。區別是redis會週期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且再此基礎上實現了master-slave(主從)同步。

  Redis是一個高性能的key-value數據庫。redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部分場合可以對關係數據庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。

官網:http://www.redis.io/documemtation


redis特點:

1.支持內存緩存,這個功能相當於memcached

2.支持持久化,這個功能相當於memcachedb,ttserver

3.數據類型更豐富。比其他key-value庫功能更強

4.支持集羣,分佈式

5.支持隊列等特殊功能



(3)MongoDB(Document-oriented)

  MongoDB是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫中功能最豐富,最像關係數據庫的。它支持的數據結構非常鬆散,累似json的bjson格式,因此可以存儲比較複雜的數據類型。Mogodb最大的特點是他支持的查詢語言非常強大,它的語法有點類似於面向對象的查詢語言,幾乎可以實現關係數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。它的特點是高性能、易部署、易使用,存儲數據非常方便。

  主要功能特性:

1.面向集合存儲,易存儲對象類型的數據

2.模式自由

3.支持動態查詢

4.支持完全索引, 包含內部對象

5.支持查詢

6.支持複製和故障恢復

7.使用高效的二進制數據存儲,包括大型對象(如視頻等)

8.自動處理碎片,以支持雲計算層次的擴展性

9.支持ruby,python,java,c++,php等多種語言

10.文件存儲格式爲bson(一種json的擴展)

11.可通過網絡訪問

默認端口27017

http://www.mongodb.org/display/DOCS/Manual

http://www.mongodb.org/display/DOCS/Home


(4)Cassandra(Column-oriented)

  Apache Cassandra是一套開源分佈式Key-Value存儲系統。它最初由Facebook開發,用於存儲特別大的數據。Facebook目前在使用此係統。

主要特性:

分佈式

基於column的結構化

高伸展性

  Cassandra的主要特點就是它不是一個數據庫,而是由一堆數據庫節點共同構成的一個分佈式網絡服務,對Cassandra的一個寫操作,會被複制到其他節點上去,對Cassandra的讀操作,也會被路由到某個節點上面去讀取。對於一個Cassandra羣集來說,擴展性能是比較簡單的事情,只管在集羣裏面添加節點就可以了。


其他不常用非關係型數據庫

HBase,MemcacheDB,Berkeley DB,Tokyo Cabinet\Tokyo Tyrant(ttserver)


二、mysql介紹及安裝

2.1 mysql數據庫優勢

(1)mysql性能卓越,服務穩定,很少出現宕機

(2)mysql開放源代碼且無版權制約,自主性及使用成本低

(3)mysql歷史悠久,社區及用戶非常活躍,遇到問題,可以尋求幫助

(4)pmysql軟件體積小,安裝使用簡單,並且易於維護,安裝及維護成本低

(5)mysql口碑效應,使得企業無需考慮就直接用之,LAMP,LEMP流行架構

(6)mysql支持多重操作系統,提供多重API接口,支持多重開發語言,特別對流行的PHP語言有很好的支持


2.2 mysql三條產品線:

第一條產品線:5.0.xx及升級到5.1.xx的產品系列  

這條產品線繼續完善與改進其用戶體驗和性能,同時增加新功能,這條路線可以說是mysql早起產品的延續系列,這一些列的產品發佈情況及歷史版本如下:

  mysql5.1是當前穩定(產品質量)發佈系列。只針對漏洞修復重新發布;沒有增加會影響穩定性的功能。

  mysql5.0是前一穩定(產品質量)發佈系列。只針對嚴重漏洞修復和安全修復重新發布;沒有增加會影響該系列的重要功能。

  mysql4.0和3.23是舊的穩定(產品質量)發佈系列。該版本不再使用,新的發佈只用來修復特別嚴重的漏洞(以前的安全問題)。


第二條產品線:5.4.xx-5.7.xx

  爲了更好的整合mysql AB公司社區和第三方公司開發的新存儲引擎,以及吸收新的實現算法等,從而更好的支持SMP架構,提高性能而做了大量的代碼重構。版本號爲從5.4.xx開始,目前發展到了5.6.x

主流:互聯網公司用mysql5.5


第三條產品線:6.0.xx-7.1.xx

  爲了更好的推廣mysql Cluster版本,以及提高mysql Cluster的性能和穩定性,以及功能改進和增加,以及改動mysql基礎功能,使其對Cluster存儲引擎提供更有效地支持與優化。版本號爲6.0.xx開發,目前發展到7.1.xx



2.3 mysql選擇建議

(1)穩定版:選擇開源的社區版的穩定版GA版本

(2)產品線:可以選擇5.1或5.5。互聯網公司主流5.5,其次是5.1和5.6。

(3)選擇mysql數據庫GA發佈後6個月以上的GA版本。

(4)要選擇前後幾個月沒有大的BUG修復的版本,而不是大量修復BUG的集中版本。

(5)最好向後較長時間沒有更新發布的版本。

(6)要考慮開發人員開發程序使用的版本是否兼容你選的版本。

(7)作爲內部開發測試數據庫環境,跑大概3-6個月時間。

(8)優先企業非核心業務採用新版本的數據庫GA版本軟件

(9)向DBA高手請教,或者在及技術氛圍好的羣裏和大家一起交流,使用真正的高手們用過的好用的GA版本產品。

(10)經過上述工序後,若是沒有重要的功能BUG或性能瓶頸,則可以開始考慮作爲任何業務數據服務的後端數據庫軟件。


2.4 mysql5.1/5.5編譯安裝

Yum install ncurses-devel –y

useradd mysql -s /sbin/nologin -M

################使用configure編譯mysql5.1################

./configure 

--prefix=/application/mysql5.1.72 \ 

--with-unix-socket-path=/application/mysql5.1.72/tmp/mysql.sock \

--localstatedir=/application/mysql5.1.72/data \

--enable-assembler \

--enable-thread-safe-client \

--with-mysqld-user=mysql \

--with-big-tables \

--without-debug \

--with-pthread \

--enable-assembler \

--with-extra-charsets=complex \

--with-readline \

--with-ssl \

--with-embedded-server \

--enable-local-infile \

--with-plugins=partition,innobase \

--with-mysqld-ldflags=-all-static \

--with-client-ldflags=-all-static

make

make install


################使用cmake編譯mysql5.5################

tar xf mysql-5.5.32.tar.gz

cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.5.32 \

-DMYSQL_DATADIR=/application/mysql-5.5.32/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.5.32/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \

-DENABLED_LOCAL_INFILE=ON \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITHOUT_PARTITION_STORAGE_ENGINE=1 \

-DWITH_FAST_MUTEXES=1 \

-DWITH_ZLIB=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_READLINE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DWITH_DEBUG=0

make

make install

ln -s /application/mysql-5.5.32/ /application/mysql


5.0-5.1使用configure  5.5-5.6使用cmake



初始化數據庫

ln -s /application/mysql5.1.72/ /application/mysql

cp /home/xiaoyi/tools/mysql-5.1.72/support-files/my-small.cnf /etc/my.cnf

echo 'export PATH=/application/mysql/bin:$PATH' >> /etc/profile

source /etc/profile

/application/mysql/bin/mysql_install_db --basedir=/application/mysql --datadir=/application/mysql/data --user=mysql

/bin/cp /home/xiaoyi/tools/mysql-5.1.72/support-files/mysql.server /etc/init.d/mysqld

chmod +x /etc/init.d/mysqld

chown -R mysql.mysql /application/mysql/data/

chmod -R 1777 /tmp/



[root@mysql-master mysql]# /etc/init.d/mysqld start

Starting MySQL. SUCCESS! 

[root@mysql-master mysql]# lsof -i:3306

COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  10762 mysql   10u  IPv4  60630      0t0  TCP *:mysql (LISTEN)

[root@mysql-master mysql]#


[root@mysql-master mysql]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.1.72 Source distribution


Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql>




三、mysql應用管理

3.1 mysql啓動與關閉原理


單實例mysql啓動

/etc/init.d/mysqld start

查看mysql端口

ss -ntulp|grep 3306

查看mysql 進程

ps -ef|grep mysql|grep -v grep


mysql啓動原理

(1)/etc/init.d/mysqld是一個shell啓動腳本,啓動後最終會調用mysqld_safe腳本,最後調用mysqld服務啓動mysql

 $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args > /dev/null 2>&1 &


(2)初始化數據庫時mysql系統輸出給出的啓動方法

mysqld_safe --user=mysql


(3)常規方法關閉數據庫

/etc/init.d/mysqld stop


(4)強制關閉數據庫方法:

killall mysqld

pkill mysqld

killall -9 mysqld


(5)優雅關閉mysql

mysqladmin -uroot -prinimei shutdown

/etc/init.d/mysqld stop

kill -USR2 `cat path/pid`


3.2登陸mysql

(1)mysql

(2)mysql -uroot

(3)mysql -uroot -p

(4)mysql -uroot -p'rinimei'

(5)mysql -uroot -prinimei


history -c 刪除所有歷史記錄

history -d 2 刪除第二條歷史記錄


查看mysql的歷史記錄

cat /root/.mysql_history 


登陸mysql後

a.登陸後默認提示符爲

mysql>

b.爲了防止操作失誤,可以標記是測試環境,寫在配置裏永久生效

mysql>prompt \u@test \r:\m:\s->

PROMPT set to '\u@test \r:\m:\s->'


命令行修改mysql提示符(臨時生效)

prompt \u@xiaoyi \r:\m:\s->


配置文件修改登陸提示符

my.cnf配置文件中[mysql]模塊下添加如下內容(注意不是mysqld),保存後,無需重啓mysql,退出當前session,重新登陸即可。如果在my.cnf配置文件中加,可以用\\,避免轉義帶來的問題。

[mysql]

prompt=\\u@xiaoyi \\r:\\m:\\s->


system可執行系統命令

mysql> system ls /tmp

1  ssh-WeqjZ36124  yum.log


3.3修改mysql密碼 

a.修改mysql root密碼方法一:命令行外修改法

 

mysqladmin -uroot -p’rinimei’ password ‘ririri’

b.修改mysql root密碼法二:sql語句修改法

mysql>update mysql.user set password=password("rinimei") where user='root';

提示:此方法適合密碼丟失後通過--skip-grant-tables參數啓動數據庫後修改密碼

警告:

1.必須指定where條件,否則全改

2.必須指定password()函數來更改密碼


c.修改管理員root密碼法三:

mysql>set password=password('rinmei');

提示:不適合--skip-grant-tables方式修改密碼


3.4找回丟失的mysql密碼

1)首先停止mysql

/etc/init.d/mysqld stop


2)使用--skip-grant-tables啓動mysql,忽略授權登陸驗證

mysqld_safe --skip-grant-tables --user=mysql &


3)直接輸入mysql進入

mysql


mysql>update mysql.user set password=password("rinimei") where user='root' and host='localhost';

mysql>flush privileges;


4)重啓服務再登陸

mysqladmin -uroot -prinimei shutdown

/etc/init.d/mysqld start

mysql -uroot -prinimei


使用二進制包報錯需要修改以下:

cp /application/mysql/bin/mysqld_safe

sed -i 's#/usr/local/mysql#/application/mysql#g' /application/mysql/bin/mysqld_safe


3.5 SQL語言

SQL結構化查詢語言

 

什麼是SQL?

    SQL,英文全稱Structured Query Language,結構化查詢語言,它是一種對關係數據庫中的數據進行定義和操作的語言方法,是大多數關係數據庫管理系統所支持的工業標準。


SQL的分類

SQL結構化查詢語言包含6個部分:

(1)數據查詢語言(DQL):

  DQL(Data Query Language),也稱數據檢索語句,用以從表中獲得數據,確定數據怎樣在應用程序給出。關鍵字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。這些DQL保留字常與其他類型的SQL語句一起使用。

mysql>select user,host from mysql.user order by user asc; 升序排列

mysql>select user,host from mysql.user order by user desc; 倒序排列


(2)數據操作語言(DML):

  DML(Data Manipulation Language),其語句包括動詞INSERT,UPDATE和DELETE。它們分別用於添加,修改和刪除表中的行(數據)。也稱爲動作查詢語言。

mysql>delete from mysql.user where user='rinimei';


(3)事物處理語言(TPL)

  它的語句能確保被DML語句影響的表的所有行及時得以更新。TPL語句包括BEGIN,TRANSACTION,COMMIT和ROLLBACK


(4)數據控制語言(DCL):

DCL全稱(Data Control Language),它的語句通過GRANT或REVOKE獲得許可,確定單個用戶和用戶組對數據庫對象的訪問。某些RDBMS可用GRANT或REVOKE控制對錶單個列的訪問。


(5)數據定義語言(DDL):

DDL(Data Definition Language),其語句包括動詞CREATE和DROP。在數據庫中創建新表或刪除表(CREATE TABLE或DROP TABLE);爲表加入索引等。DDL包括許多人與數據庫目錄中獲得數據有關的保留字。它也是動作查詢的一部分。


(6)指針控制語言(CCL):

CCL(Cursor Control Language),它的語句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨進行的操作。


小結:SQL語句最常見的分類一般就是3類:

DDL-數據定義語言(CREATE,ALTER,DROP)

DML-數據操作語言(SELECT,INSERT,DELETE,UPDATE)

DCL-數據控制語言(GRANT,REVOKE,COMMIT,ROLLBACK)


3.6數據庫字符集

數據庫字符集

創建數據庫

a.create database xiaoyi_default;(數據庫名不能數字開頭)


查看建表語句

show create database xiaoyi\G


mysql> show create database xiaoyi\G

*************************** 1. row ***************************

       Database: xiaoyi

Create Database: CREATE DATABASE `xiaoyi` /*!40100 DEFAULT CHARACTER SET latin1 */

1 row in set (0.00 sec)


mysql> show collation;

查看所有collate


b.建立一個名爲xiaoyi_gbk的GBK字符集數據庫

create database xiaoyi_gbk default character set gbk collate gbk_chinese_ci;

mysql> show create database xiaoyi_gbk\G

*************************** 1. row ***************************

       Database: xiaoyi_gbk

Create Database: CREATE DATABASE `xiaoyi_gbk` /*!40100 DEFAULT CHARACTER SET gbk */

1 row in set (0.00 sec)


c.創建一個名爲xiaoyi_utf8的utf8字符集數據庫

create database xiaoyi_utf8 character set utf8 collate utf8_general_ci;


小結:創建不同字符集格式的數據庫命令(編譯時未指定)

create database xiaoyi;  ##默認數據庫配置,相當於創建拉丁字符集數據庫。

create database olbdoy_gbk default character set gbk collate gbk_chinese_ci; 

##創建gbk字符集數據庫

create database olbdoy_utf8 character set utf8 collate utf8_general_ci;

##創建utf8字符集數據庫


提示:如果編譯的時候指定了特定的字符集,則以後創建對應的數據庫就不需要指定字符集了

--DDEFAULT_CHARSET=utf8 \

--DDEFAULT_COLLATION=utf8_general_ci \


數據庫要支持創建庫的字符集,例如

-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \



3.7顯示-連接-刪除等數據庫的管理

顯示數據庫

show database like '%yi%';


顯示當前數據庫

select database();


刪除數據庫

drop database xiaoyi;


連接數據庫

use xiaoyi;


查看版本

select version();


查看當前用戶

select user();


查看當前時間

select now();


查表

切到數據庫裏面去查看

show tables;

show tables like 'user'

show tables from xiaoyi_gbk; #查看指定庫中的表。

show tables in xiaoyi_gbk;


刪除mysql系統多餘帳號

語法:drop user "user"@"主機域" #注意引號,可以是單或雙引號,但是不能不加

drop user 'root'@'xiaoyi';

drop user ''@'xiaoyi';

drop user ''@'localhost'; #沒有的部分就用兩個單引號代替即可。


注意:

如果drop刪除不了(一般是特殊字符或大寫),可以用下面方式刪除(以root用戶,xiaoyi主機爲例)

delete from mysql.user where user='root' and host='xiaoyi';

flush privileges;


創建mysql用戶及賦予用戶權限

grant all on db1.* to 'user'@'localhost' identified by 'rinimei';


create user 'user'@'localhost' identified by 'rinimei';

grant all on db1.* to 'user'@'localhost';

#以上命令相當於一條


show grants for xiaoyi@'localhost';



授權局域網內主機遠程連接數據庫

a.百分號匹配法

grant all on *.* to test@'10.0.0.%' identified by 'test123';

b.子網掩碼匹配法

grant all on *.* to test@'10.0.0.0/255.255.255.0' identified by 'test123';


1.本地mysql -uroot -prinimei 連接數據庫相當於mysql -uroot -prinimei -hlocalhost

2.要連接10.0.0.7的數據庫,命令爲mysql -utest -prinimei -h10.0.0.7

grant all on *.* to test@'10.0.0.%' identified by 'test123';

提示:上述命令的意思是授權10.0.0.%,匹配這個字符串IP地址的所有主機可以連接數據庫。百分號%匹配所有10.0.0.0/24內的主機。

3.通過php服務器連接mysql服務器的代碼寫法爲:

<?php

//$link_id=mysql_connect('主機名',‘用戶’,‘密碼’);

$link_id=mysql_connect('10.0.0.7','test','test123')or mysql_error();

if($link_id){

echo "mysql successful by xiaoyi!";

}else{

echo mysql_error();

}

?>


mysql用戶可以授權的權限有哪些

1.先看看前面授權過的xiaoyi的權限

help revoke

revoke insert on test.* from xiaoyi@'localhost';

show grants for xiaoyi@'localhost';

| GRANT SELECT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `test`.* TO 'xiaoyi'@'localhost' |


在shell界面下執行mysql命令

mysql -uroot -prinimei -e "show grants for xiaoyi@localhost;"



3.8 mysql建表語句及表結構

表操作


(1)以默認字符集創建庫

create database xiaoyi;

show create database xiaoyi \G


(2)建立表

建表語句

use xiaoyi

create table student(

id int(4) not null,

name char(20) not null,

age tinyint(2) not null default '0',

dept varchar(16) default null

);


(3)mysql生成的建表語句

mysql> show create table student\G 

*************************** 1. row ***************************

       Table: student

Create Table: CREATE TABLE `student` (

  `id` int(4) NOT NULL,

  `name` char(20) NOT NULL,

  `age` tinyint(2) NOT NULL DEFAULT '0',

  `dept` varchar(16) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.00 sec)


int 數字類型

char 定長字符類型

tinyint 很小的數字類型

varchar 變長字符類型

ENGINE=InnoDB 引擎

CHARSET=latin1 字符集


mysql5.1及以前默認引擎爲MyISAM

mysql5.5以後默認引擎爲InnoDB


查看錶結構以及建表語句

查看建立的表結構

desc student;

show columns from student;


查看已建表的語句

show create table student\G


3.9 mysql索引

索引就像書的目錄一樣,如果在字段上建立了索引,那麼以索引列爲查詢條件時可以加快查詢速度,這是mysql優化的重要內容之一


(1)創建主鍵索引

查詢數據庫,按主鍵查詢是最快的,每個表只能有一個主鍵列,但是可以有多個普通索引列。主鍵列要求列的所有內容必須唯一,而普通索引列不要求內容必須唯一。


建立主鍵索引的方法:

①在建表時,可以增加建立主鍵索引的語句

create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

age tinyint(2) NOT NULL default '0',

dept varchar(16) default NULL,

primary key(id),

KEY index_name(name)

);

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)


提示:

1.primary key(id)主鍵

2.KEY index_name(name)name字段普通索引


②建表後通過alter命令增加主鍵索引(不這樣幹)

a.主鍵列不能重複創建,必須先刪除上面配置

alter table student drop primary key;


利用alter命令修改id列爲自增主鍵列

alter table student change id id int primary key auto_increment;


alter table student change id id int(4); 

alter table student drop primary key;


(2)創建普通索引

①在建表時,可以增加簡歷普通索引的語句

create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

age tinyint(2) NOT NULL default '0';

dept varchar(16) default NULL,

primary key(id),

KEY index_name(name)

);


②建表後利用alter增加普通索引

刪除建表時的index_name索引,

alter table student drop index index_name,

在name列上添加索引,索引名爲index_name,

alter table student add index index_name(name);


提示:PRI爲主鍵的標識,MUL爲普通索引的標識。


(3)對字段的前n個字符創建普通索引

當遇到表中比較大的列時,列內容的前n個字符在所有內容中已經接近唯一時,這時可以對列的前n個字符簡歷索引,而無需對整個列建立索引,這樣可以節省創建索引佔用的系統空間,以及降低讀取和更新維護索引消耗的系統資源。


對字段的前n個字符創建普通索引的語法:

create index index_name on student(name(8)); #條件列前n個字符創建索引

操作實踐:

在dept系別上,前8個字符創建索引,此列總共長度爲16個。


show index from student\G



(4)爲表的多個字段創建聯合索引

如果查詢數據的條件是多列時,我們可以爲多個查詢的列創建聯合索引,甚至,可以爲多列的前n個字符列創建聯合索引:

create index ind_name_dept on student(name,dept);

show index from student\G



create index ind_name_dept on student(name(8),dept(10))


提示:按條件列查詢數據時,聯合索引是有前綴生效特性的。

index(a,b,c)僅a,ab,abc三個查詢條件列可以走索引。


(5)創建唯一索引(非主鍵)

create unique index index_name on student(name);


(6)索引列的創建及生效條件

問號1.既然索引可以加快查詢速度,那麼就給所有的列建索引?

解答:索引不但佔用系統空間,更新數據時還需要維護索引數據的,因此,索引是一把雙刃劍,並不是越多越好

例如:數十到幾百行的小表上無需建立索引,寫繁瑣,讀少的業務要少建立索引。


問號2.到底在哪些列上創建索引呢?

 select user,host from mysql.user where host=  索引一定要創建在where後的條件列,而不是select後的選擇數據的列。另外我們要儘量選擇在唯一值多的大表上建立索引。


創建索引相關命令集合:

1.創建索引相關命令集合

創建主鍵索引:

alter table student change id id int primary key auto_increment;

刪除主鍵索引:

alter table student drop primary key;


創建普通索引:

alter table student add index index_dept(dept(8));

(根據列的前n個字符創建索引)

create index index_dept on student(dept(8));

刪除普通索引

alter table student drop index index_dept;

drop index index_dept on student;


根據多個列創建聯合索引:

create index ind_name_dept on student(name,dept);

(根據多個列的前n個字符創建聯合索引)

create index ind_name_dept on student(name(8),dept(10))


創建唯一索引:

create unique index uni_ind_name on student(name);


①要在表的列上創建索引

②索引會加快查詢速度,但是會影響更新的速度

③索引不是越多越好,要在頻繁查詢的where後的條件列上創建索引

④小表或唯一值極少的列上不建立索引,要在大表以及不同內容多的列上創建索引



3.10 DML語句之insert

往表中插入數據

1.新建一個簡單的測試表test

create table `test` (

`id` int(4) NOT NULL AUTO_INCREMENT,

`name` char(20) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;


2.往表中插入數據的不同的語法例子:

(1)按規矩指定所有列名,並且每列都插入值

insert into test(id,name) values(1,'xiaoyi');

(2)由於id列爲自增的,所以,可以只在name列插入值

insert into test(name) values('girl');

(3)如果不指定列,就要按規矩爲每列都插入恰當的值

insert into test values(3,'inca');

(4)批量插入數據方法,提升效率

insert into test values(4,'zuma'),(5,'kaka');

insert into `test` values(1,'xiaoyi'),(2,'girl'),(3,'inca'),(4,'zuma'),(5,'kaka');


刪除表中所有數據

delete from test;


(5)測試完畢,退出數據庫,然後備份上樹數據,留着備用:

mysqldump -uroot -prinimei -B xiaoyi > /opt/xiaoyi_bak.sql

-A備份所有庫


(6)備份後檢查備份的sql數據內容:過濾無用信息

grep -E -v "#|\/|^$|--" /opt/xiaoyi_bak.sql 


提示:

-A表示所有庫,後面不能在指定xiaoyi_gbk庫了。

5.1.68版本:

mysqldump -uroot -prinimei -A -B --events > /tmp/xiaoyi_bak.sql


3.11 DQL之select

查詢數據

1.查看test中所有數據

a.進入指定庫中查詢

use xiaoyi

select * from test;


(1)查看錶test中的兩行數據

select id,name from test limit 2;

select id,name from test limit 0,2;


(2)指定固定條件查詢

select id,name from test where id=1;

select id,name from test where name='girl';

提示:字符類型的查詢條件要帶引號

select id,name from test where id=2 and name='girl';

select id,name from test where id=5 or name='girl';


(3)指定固定條件範圍查數據

select id,name from test where id>2 and id<4;


(4)其他查詢功能

排序功能

select id,name from test order by id;

select id,name from test order by id asc;

select id,name from test order by id desc;


3.12 DQL之select多表連表查詢


=============================================  


--學生表:Student(Sno,Sname,Ssex,Sage,Sdept)  


-------- (學號-主鍵,姓名,性別,年齡,所在系)  


=============================================  

drop  tables  student;  

create  table  student(  

Sno  int(10)  NOT  NULL  COMMENT  '學號',  

Sname  varchar(16)  NOT  NULL  COMMENT  '姓名',  

Ssex  char(2)  NOT  NULL  COMMENT  '性別',  

Sage  tinyint(2)    NOT  NULL  default  '0'  COMMENT  '學生年齡',  

Sdept  varchar(16)    default  NULL    COMMENT  '學生所在系別',    

PRIMARY  KEY    (Sno)  ,  

key  index_Sname  (Sname)  

)  ENGINE=InnoDB  AUTO_INCREMENT=1  DEFAULT  CHARSET=utf8;  

=============================================  



------課程表:Course(Cno,Cname,Ccredit)  

>------ (課程號-主鍵,課程名,學分)  

>

============================================  

create  table  course(  

Cno  int(10)  NOT  NULL  COMMENT  '課程號',  

Cname  varchar(64)  NOT  NULL  COMMENT  '課程名',  

Ccredit  tinyint(2)  NOT  NULL  COMMENT  '學分',  

PRIMARY  KEY    (Cno)    

)  ENGINE=InnoDB  AUTO_INCREMENT=1  DEFAULT  CHARSET=utf8;  


============================================  



------選課表:  SC(Sno,Cno,Grade)  


------ (學號-主鍵,課程號-主鍵,成績)  


------其中SC 表主鍵參照Student,Course 表  


==============================================  


CREATE  TABLE  `SC`  (  

      SCid  int(12)  NOT  NULL  auto_increment  COMMENT  '主鍵',  

    `Cno`  int(10)  NOT  NULL  COMMENT  '課程號',  

    `Sno`  int(10)  NOT  NULL  COMMENT  '學號',  

    `Grade`  tinyint(2)  NOT  NULL  COMMENT  '學生成績',  

    PRIMARY  KEY    (`SCid`)  

)  ENGINE=InnoDB  DEFAULT  CHARSET=utf8;  



往關聯表中填充數據

1.學生表插入數據:

INSERT  INTO  student  values(0001,'宏志','男',30,'計算機網絡');  

INSERT  INTO  student  values(0002,'碩碩  ','男',30,'computer  application');  

INSERT  INTO  student  values(0003,'xiaoyi','男',28,'物流管理');  

INSERT  INTO  student  values(0004,'脈動','男',29,'computer  application');  

INSERT  INTO  student  values(0005,'girl','女',26,'計算機科學與技術');  

INSERT  INTO  student  values(0006,'瑩瑩','女',22,'護士');  


2.課程表插入數據:

INSERT  INTO  course  values(1001,'Linux 中高級運維',3);  

INSERT  INTO  course  values(1002,'Linux 高級架構師',5);  

INSERT  INTO  course  values(1003,'MySQL 高級Dba',4);  

INSERT  INTO  course  values(1004,'Python 運維開發',4);  

INSERT  INTO  course  values(1005,'Java  web 開發',3);  


3.選課表插入數據

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1001,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1002,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1003,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0001,1004,6);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1001,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1002,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0002,1004,8);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1001,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1002,4);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0003,1004,8);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1001,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1002,1);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0004,1004,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1001,5);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1002,3);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1003,2);

INSERT  INTO  SC(Sno,Cno,Grade)    values(0005,1004,9);


mysql> select student.Sno,student.Sname,course.Cname,SC.Grade from student,course,SC where student.Sno=SC.Sno and course.Cno=SC.Cno;

+-----+----------+-----------------------+-------+

| Sno | Sname    | Cname                 | Grade |

+-----+----------+-----------------------+-------+

|   1 | 宏志     | Linux 中高級運維      |     4 |

|   2 | 碩碩     | Linux 中高級運維      |     3 |

|   3 | xiaoyi   | Linux 中高級運維      |     4 |

|   4 | 脈動     | Linux 中高級運維      |     1 |

|   5 | girl     | Linux 中高級運維      |     5 |

|   1 | 宏志     | Linux 高級架構師      |     3 |

|   2 | 碩碩     | Linux 高級架構師      |     2 |

|   3 | xiaoyi   | Linux 高級架構師      |     4 |

|   4 | 脈動     | Linux 高級架構師      |     1 |

|   5 | girl     | Linux 高級架構師      |     3 |

|   1 | 宏志     | MySQL 高級Dba         |     1 |

|   2 | 碩碩     | MySQL 高級Dba         |     2 |

|   3 | xiaoyi   | MySQL 高級Dba         |     2 |

|   4 | 脈動     | MySQL 高級Dba         |     2 |

|   5 | girl     | MySQL 高級Dba         |     2 |

|   1 | 宏志     | Python 運維開發       |     6 |

|   2 | 碩碩     | Python 運維開發       |     8 |

|   3 | xiaoyi   | Python 運維開發       |     8 |

|   4 | 脈動     | Python 運維開發       |     3 |

|   5 | girl     | Python 運維開發       |     9 |

+-----+----------+-----------------------+-------+

20 rows in set (0.00 sec)


mysql>


3.13 DML之update

更改表數據

update test set name=’yige’ where id=3;

mysql> update test set name='yige' where id=3;

Query OK, 1 row affected (0.02 sec)

Rows matched: 1  Changed: 1  Warnings: 0


mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | xiaoyi |

|  2 | girl   |

|  3 | yige   |

|  4 | zuma   |

|  5 | kaka   |

+----+--------+

5 rows in set (0.00 sec)


mysql>


3.14 DML之alter


alias mysql='mysql -U'

#不加where不允許修改表a


刪除表中數據

delete from test where id=1;

delete from test where id>3;

提示:不加條件就是全部刪除,也是非常危險的操作,delete from test,這裏就不演示了


truncate table test;  #執行清空命令


truncate table test;和delete from test;區別

1.truncate table test;更快,清空物理文件

2.delete from test;邏輯清楚,按行刪。


增刪改表的字段

命令語法:

alter table 表名 add 字段 類型 其他;


alter table test add sex char(4);


alter table test add age char(4) after name;


alter table test add qq varchar(15) first;

 

alter table test add firstphoto_url varchar(255) default null comment ‘第一張土圖片’;


修改字段

alter table test change qq msn tinyint;


更改表名


rename法:

rename table test to test1;


alter法:

alter table olbdoy rename to test;


四、mysql字符集

4.1 數據庫字符集介紹

  簡單的說,字符集就是一套文字符號及其編碼、比較規則的集合,第一個計算機字符集ASC2

  mysql數據庫字符集包括字符集(CHARACTER)和校對規則(COLLATION)兩個概念。其中,字符集是用來定義mysql數據字符串的存儲方式。而校對規則則是定義比較字符串的方式。


4.2 mysql數據庫常見字符集介紹

  在互聯網環境中,使用mysql時常用的字符集有:

GBK2不是國際標準

UTF-83中英文混合的環境,建議使用此字符集

latin11mysql的默認字符集

utf8mb44UTF-8 Unicode


4.3 如何選擇合適的字符集?

(1)如果處理各種各樣的文字,發佈到不同語言國家地區,應選Unicode字符集,對mysql來說就是UTF-8(每個漢字三字節),如果應用需處理英文,僅有少量漢字UTF-8更好。

(2)如果只需支持中文,並且數據量很大,性能要有也很高,可選GBK(定長 每個漢字佔雙字節,英文也佔雙字節),如果需大量運算,比較排序等 定長字符集,更快,性能高。

(3)處理移動互聯網業務,可能需要使用utf8mb4字符集


4.4 mysql插入中文數據不亂碼深度剖析

1.先看下Mysql默認情況下設置的字符集

mysql>show variables like 'character_set%';

不同字符集參數的含義如下:

+--------------------------+-------------------------------------------+

| Variable_name            | Value                                     |

+--------------------------+-------------------------------------------+

| character_set_client     | utf8 #客戶端字符集;                       |

| character_set_connection | utf8  #連接字符集;       |

| character_set_database   | latin1#數據庫字符集,配置文件指定或建庫建表指定|

| character_set_filesystem | binary                                    |

| character_set_results    | utf8  #返回結果字符集;       |

| character_set_server     | latin1#服務器字符集,配置文件指定或建庫表指定|

| character_set_system     | utf8                                      |

| character_sets_dir       | /application/mysql-5.5.32/share/charsets/ |

+--------------------------+-------------------------------------------+

更改系統字符集變量後,查看mysql中字符集的變化。

echo $LANG

zh_CN.UTF8

mysql -uroot -prinimei -e "show variables like 'character_set%';"


set names 原理:

character_set_client

character_set_connection

character_set_results


mysql命令參數--default-character-set=latin1在做什麼?

mysql -uroot -prinimei --default-character-set=latin1 xiaoyi < test.sql

mysql -uroot -prinimei -e "show variables like'character_set%';"


通過mysql命令加上字符集參數指定latin1字符集導入test.sql語句

mysql -uroot -prinimei -e "set names latin1;select * from xiaoyi.student;"



mysql -uroot -prinimei --default-character-set=latin1


不亂碼的思想:建議中英文環境選擇utf8

(1)linux系統服務端

cat /etc/sysconfig/i18n

#LANG="zh_CN.GB2312"

LANG="zh_CN.utf8"

提示:linux客戶端也要更改字符集


(2)mysql客戶端

臨時:

set names utf8

永久:

更改my.cnf客戶端模塊的參數,可以實現set names utf8的效果,並且永久生效。


[client]

default-character-set=latin1

提示:無需重啓服務,退出重新登陸就生效。相當於set names latin1;


實際改動:

character_set_client

character_set_connection

character_set_results



(3)mysql服務端

[mysqld]

default-character-set=utf8適合5.1以前版本

character-set-server=utf8適合5.5


實際改動:

character_set_database

character_set_server


(4)mysql數據庫中建庫建表

create database xiaoyi_utf8 default character set utf8 collate utf8_general_ci;


create table `student` (

`id` int(4) not null auto_increment,

`name` char(20) not null,

primary key(`id`)

) engine=innodb auto_increment=10 default charset=utf8


(5)開發的程序的字符集:


4.5 數據字符集修改案例


對於已有的數據庫想修改字符集不能直接通過"alter database character set *"或"alter table tablename character set *",這兩個命令都沒有更新已有記錄的字符集,而只是對新創建的表或者記錄生效。


已經有記錄的字符的調整,必須先將數據導出,經過修改字符集後重新導入後纔可完成。

修改數據庫默認編碼:

alter database[your db name]charaset[your character setting]


下面模擬將utf8字符集的數據庫修改成GBK字符集的實際過程。

(1)導出表結構

mysqldump -uroot -p --default-character-set=latin1 -d dbname > alltable.sql

--default-character-set=gbk 表示以GBK字符集進行連接 -d 只導表結構


(2)編輯alltable.sql將latin1改成GBK


(3)確保數據庫不再更新,導出所有數據

mysqldump -uroot -p --quick --no-create-info(-t) --extended-insert --default-character-set=latin1 dbname > alldata.sql


參數說明:

--quick:用於轉儲大的表,強制mysqldump從服務器一次一行的檢索數據而不是檢索所有行,並輸出前cache到內存中。

--no-create-info:不創建create table語句

--extended-insert:使用包括幾個values列表的多行insert語法,這樣文件更小,IO也小,導入數據時會非常快。

--default-character-set=latin1#按照原有字符集導出數據,這樣導出的文件中,所有中文都是可見的,不會保存成亂碼。


(4)打開alldata.sql將set names latin1修改成set names gbk;


(5)建庫

create database dbname default charset gbk;


(6)創建表,執行alltable.sql

mysql -uroot -p dbname < alltable.sql


(7)導入數據

mysql -uroot -p dbname < alldata.sql



五、mysql備份/增量備份

5.1 備份單個數據庫

語法:mysqldump -u 用戶名 -p 數據庫名 > 備份的文件名


範例1:備份名字爲xiaoyi的庫

a.查看備份前的數據

mysql -uroot -prinimei -e "use xiaoyi;show tables;select * from student;"

b.執行備份的命令

mysqldump -uroot -prinimei xiaoyi > /opt/mysql_bak.sql

c.檢查備份的結果

egrep -v "#|\*|--|^$" /opt/mysql_bak.sql


DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

LOCK TABLES `test` WRITE;

INSERT INTO `test` VALUES (1,'xiaoyi'),(2,'girl'),(3,'inca'),(4,'zuma'),(5,'kaka');

UNLOCK TABLES;



範例2:設置字符集參數備份解決亂碼問題

a.查看備份前數據庫客戶端及服務端的字符集設置

mysql -uroot -prinimei -e "show variables like '%character%'"

b.指定對應的字符集備份,這裏爲--default-character-set=latin1

執行結果:

mysqldump -uroot -prinimei --default-character-set=latin1 xiaoyi > /opt/mysql_bak.sql



範例3:

備份時加-B參數(備份時,添加庫的語句和切換庫的語句也備份)

mysqldump -uroot -prinimei --default-character-set=latin -B xiaoyi > /opt/mysql_bak_b.sql

mysql -uroot -prinimei < /opt/mysql_bak_b.sql

mysql -uroot -prinimei -e "select * from xiaoyi.student;" 

和前面的備份文件相比,看看-B參數的作用

>CREATE DATABASE /*!32312 IF NOT EXISTS*/ `xiaoyi` /*!40100 DEFAULT CHARACTER SET latin1 */;

>

>USE `xiaoyi`;



範例4:優化備份文件大小減少輸出註釋

--compact參數說明:

###(測試時用的比較多)也可以優化輸出的大小,讓內容更少,適合調試。

--compact Give less verbose output (useful for debugging).Disables

 structure comments and header/footer constructs. Enables 

 options --skip-add-drop-table --no-set-names

 --skip-disable-keys --skip-add-locks

參數說明:該選項使得輸出內容更簡潔,不包括默認選項中各種註釋。有如下幾個參數的功能。

--skip-add-drop-table  --no-set-names  --skip-disable-keys  --skip-add-locks


範例5:

指定壓縮命令壓縮備份的mysql數據

mysqldump -uroot -prinimei --default-character-set=latin1 -B xiaoyi|gzip > /opt/mysql_bak_b.sql.gz

效率提高將近3倍


通過以上例子得出什麼結論?

a.導出數據用-B參數

b.用gzip對備份的數據壓縮


5.2 mysqldump邏輯備份工作原理


mysqldump的工作原理

利用mysqldump命令備份數據的過程,實際上就是把數據從mysql庫裏以邏輯的sql語句的形式直接輸出或者生成備份的文件的過程


5.3 備份多個庫

備份多個庫及多個參數練習

a.操作結果

mysqldump -uroot -prinimei -B xiaoyi xiaoyi_gbk|gzip > /opt/all_bak.sql.gz

b.-B參數說明

提示:-B參數是關鍵,表示接多個庫,並且增加use db,和create database db的信息

#####(生產環境常用)

mysql -uroot -prinimei -B xiaoyi xiaoyi_gbk|gzip > /opt/mul.sql.gz


5.4 多表備份

備份多個表

    語法:mysqldump -uroot -prinimei 數據庫名 表名1 表名2 > 備份的文件名

mysqldump -uroot -prinimei --compact xiaoyi student test > /opt/table.sql


企業需求:一個庫裏有大表有小表,有時可能需要只恢復某一個小表,上述的多表備份文件很難拆開,就會像沒有分庫那樣導致恢復某一個小表很麻煩。

  那麼又如何進行分表備份呢?如下,和分庫的思想一樣,每執行一條語句備份一個表,生成不同的數據文件即可

mysqldump -uroot -prinimei test > xiaoyi_test.sql

mysqldump -uroot -prinimei test1 > xiaoyi_test1.sql



分表備份缺點:文件多,很碎

1.備一個完整全備,再做一個分庫分表備份

2.腳本批量恢復多個SQL文件


5.5 只備份表結構及數據

備份數據庫表結構(不包含數據)

利用mysqldump -d參數只備份表的結構,例:備份xiaoyi庫的所有表的結構

mysqldump -uroot -prinimei -B -d xiaoyi > /opt/t.sql

egrep -v "#|\*|--|^$" /opt/t.sql


備份數據庫數據

mysqldump -uroot -prinimei --compact -t xiaoyi student


備份整個數據庫

mysqldump -uroot -prinimei -A -B --events|gzip > /opt/a.sql.gz



-F 切割binlog


mysqldump -uroot -prinimei --master-date=1 --compact xiaoyi

找到binlog位置

mysqldump的關鍵參數說明

關鍵參數:mysqldump --help

1.-B指定多個庫,增加建庫語句和use語句

2.--compact去掉註釋,適合調試輸出,生產不用

3.-A備份所有庫

4.-F刷新binlog日誌

5.--master-data增加binlog日誌文件名及對應的位置點

6.-x,--lock-all-tables

  Locks all tables across all databases.This is achieved 

by taking a global read lock for the duration of the

whole dump.Automatically turns --single-transaction and 

--lock-tables off

7.-l,--lock-tables Lock all tables for read.

8.-d 只備份表結構

9.-t 只備份數據

10.--single-transaction 適合innodb事物數據庫備份

  InnoDB表在備份時,通常啓用選項--single-trasaction來保證備份的一致性,實際上它的工作原理是設定本次會話的隔離級別爲:REPEATABLE READ,以確保本次會話(dump)時,不會看到其他會話已經提交了的數據。


myisam:

mysqldump -uroot -prinimei -A -B --master-data=2 -x --events|gzip > /opt/all.sql.gz


5.6 myisam與innodb引擎備份

myisam:

mysqldump -uroot -prinimei -A -B --master-data=2 -x --events|gzip > /opt/all.sql.gz


innodb:

mysqldump -uroot -prinimei -A -B --master-data=2 --events --single-transaction | gzip > /opt/all.sql.gz


#for MyISAM

mysqldump --user=root --all-databases --flush-privileges --lock-all-tables \

--master-data=1 --flush-logs --triggers --routines --events \

--hex-blob > $BACKUP_DIR/flush_dump_$BACKUP_TIMESTAMP.sql


#for InnoDB

mysqldump --user=root --all-databases --flush-privileges --single-transaction \

--master-data=1 --flush-logs --triggers --routines --events \

--hex-blob > $BACKUP_DIR/flush_dump_$BACKUP_TIMESTAMP.sql


5.7 source恢復mysql數據

a.利用source命令恢復數據庫

mysql>use 數據庫

mysql>source xiaoyi_db.sql

b.利用mysql命令恢復數據庫

cat test.sql

use xiaoyi

insert into test(name) values("xiaoyi");

mysql -uroot -prinimei < test.sql

mysql -uroot -prinimei -e "select * from xiaoyi.test;"|tail -1


備份庫時指定-B,恢復時無需指定庫恢復,爲什麼?

因爲-B參數帶了use xiaoyi還會有create database xiaoyi;

而恢復時指定庫就類似於use xiaoyi;

mysql -uroot -prinimei > insert.sql

否則只能用如下方法

mysql -uroot -prinimei xiaoyi < insert.sql

因此建議備份庫時指定-B。


說明:mysql不光可以恢復mysqldump的備份,只要是sql語句,都可以通過Mysql命令執行到數據庫中。


5.8 分庫備份後mysql分庫恢復


通過腳本讀指定的庫和表,調用mysql命令恢復

gzip -d *

for dbname in `ls *.sql|sed 's#_bak.sql##g'`;

do

mysql -uroot -prinimei < ${dbname}_bak.sql

done


六、mysql進程狀態binlog

6.1 mysql進程狀態

MyISAM引擎存放索引的緩衝區

/etc/my.cnf

[mysqld]

key_buffer


mysql -uroot -prinimei -e "show variables;" | grep key_buffer

mysql>show variables like 'key_buffer%';

set global key_buffer_size=1024*1024*32;


重啓生效方法:

vim /etc/my.cnf

[mysqld]

key_buffer_size = 32K

mysql>set global key_buffer_size=1024*32

mysql>show variables like 'key_buffer%';


小結:

show status; 查看當前會話的數據庫狀態信息

show global status; 查看整個數據庫運行狀態信息,很重要要分析並做好監控

show processlist; 查看正在執行的sql語句,看不全

show full processlist;查看正在執行的完整sql語句,全

set global key_buffer_size = 32777218 不重啓數據庫調整數據庫參數,直接生效,重啓後失效

show variables; 查看數據庫的參數信息,例如:my.cnf裏參數的生效情況


6.2 mysqlbinlog

mysqlbinlog:解析mysqlbinlog日誌

mysql的binlog日誌是什麼?

數據目錄下的如下文件就是mysql的binlog日誌

mysql-bin.000001

mysql-bin.000002

mysql的binlog日誌作用是什麼?

用來記錄mysql內部增刪改等對mysql數據庫有更新的內容的記錄。


mysqlbinlog mysql-bin.000020 > all.sql

mysqlbinlog -d xiaoyi mysql-bin.000020 > xiaoyi.sql


基於位置點的增量恢復

1.指定開始位置和結束位置

mysqlbinlog mysql-bin.000021 --start-position=510 --stop-position=1312 -r pos.sql

輸出 初始位置510,結束位置1312的所有binlog日誌到pos.sql

注意:結尾的日誌點比較特殊,不會被包含。即輸出1312pos以前的binlog.位置點信息一般要實際存在,不能亂指定。

2.指定開始位置到文件結束

mysqlbinlog mysql-bin.000021 --start-position=510 pos510-end.sql

輸出 初始位置510,結束位置到文件結尾的所有binlog到pos510-end.sql,當然,你也可以指定庫名輸出binlog,如:

mysqlbinlog mysql-bin.000021 --start-position=510 -r pos510-end-xiaoyi.sql -d xiaoyi

-r 重定向 -d 指定庫

3.從文件開頭到指定位置結束

mysqlbinlog mysql-bin.000021 --stop-position=510 -r start-pos510-xiaoyi.sql -d xiaoyi


基於時間點的增量恢復

1.指定開始時間和結束時間

mysqlbinlog mysql-bin.000021 --start-datetime='2015-03-19 02:58:53' --stop-datetime='2015-03-19 03:22:44' -r time.sql

  上面語句將顯示2015-03-19 02:58:54---2015-03-19 03:22:44時間段的binlog,並輸出到time.sql


2.指定開始時間到文件結束

mysqlbinlog mysql-bin.000021 --start-datetime='' -d xiaoyi -r time.sql

  這個語句只有開始時間,到日誌結尾,xiaoyi數據庫的binlog輸出到time.sql


3.從文件開頭到指定結束時間

mysqlbinlog mysql-bin.000021 --stop-datetime='' -d xiaoyi -r time.sql

  這個語句只有結束時間,從日誌開頭到''截止,xiaoyi數據庫的binlog輸出



mysqlbinlog

-d截取指定庫的binlog

按照位置截取:

mysqlbinlog mysql-bin.000020 --start-position=365 --stop-position=456 -r pos.sql

按照時間接取:

mysqlbinlog mysql-bin.000020 --start-datetime='2015-03-19 03:22:44' --stop-datetime='2015-03-19 03:22:44' -r time.sql



binlog功能怎麼打開?

grep log-bin /etc/my.cnf



6.3 mydqldump(--master-data)

mysqldump-master-data

myisam備份命令:

mysqldump -uroot -prinimei -A -B -F --master-data=2 -x --events|gzip > /opt/all.sql.gz

innodb備份命令:

mysqldump -uroot -prinimei -A -B -F --master-data=2 --events --single-transaction|gzip > /opt/all.sql.gz


--master-data=2

--CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000020',MASTER_LOG_POS=1191;


--master-data=1

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000020',MASTER_LOG_POS=1191;



七、mysql主從複製

mysql主從複製

7.1 mysql主從複製介紹

  mysql支持單向、雙向、鏈式級聯、實時、異步複製。在複製過程中,一臺服務器充當主服務器(master),而另一個或多個其他的服務器充當從服務器(slave).

  複製可以是單向:M→S,也可以是雙向M←→M,當然也可以多M環狀同步等。

  如果設置了鏈式級聯複製,那麼,從(slave)服務器本身除了充當從服務器之外,也會同時充當其下面從服務器的主服務器。

  鏈式級聯複製類似A→B→C→D的複製形式

(1)單向主從同步模式(√)

   一主兩從及多從的mysql架構方案(√)

(2)雙向主從同步(互爲主從)(!)

(3)線性級聯單向雙主同步(√)

(4)環狀級聯單向多主同步(!)

(5)環狀級聯單向多主多從同步


7.2 mysql主從同步原理

 


7.3 mysql主從同步部署

(1)定義服務器角色

mysql master:192.168.11.2port:3306

mysql slave:192.168.11.3 port:3306


(2)定義server-id

vim /etc/my.cnf

[mysqld]

log-bin = mysql-bin

server-id = 1

提示:

(1)上面兩個參數要放在my.cnf中的[mysqld]模塊下,否則會報錯

(2)server-id的值使用服務器ip地址的最後8位如19,目的是避免不同機器或實例ID重複(不適合多實例)0<server-id<2的32次方-1的自然數

(3)要先在my.cnf配置文件中查找相關參數,並按照要求修改。不存在時在添加參數,切記,參數不能重複

(4)修改my.cnf配置後需要重啓數據庫,命令爲:/etc/init.d/mysql restart,注意要確認真

正重啓了


檢查配置後的結果

egrep "server-id|log-bin" /etc/my.cnf

[root@mysql-master data]# egrep "server-id|log-bin" /etc/my.cnf

server-id= 2

log-bin=mysql-bin


[root@mysql-master data]# pwd

/application/mysql/data

[root@mysql-master data]# ll

total 20536

drwx------. 2 mysql mysql     4096 Dec 14 16:44 gong

drwx------. 2 mysql mysql     4096 Dec 14 17:18 gongyi

-rw-rw----. 1 mysql mysql 10485760 Dec 15 14:19 ibdata1

-rw-rw----. 1 mysql mysql  5242880 Dec 15 14:19 ib_logfile0

-rw-rw----. 1 mysql mysql  5242880 Dec 13 15:10 ib_logfile1

drwx------. 2 mysql root      4096 Dec 13 15:07 mysql

-rw-rw----. 1 mysql mysql      106 Dec 15 14:19 mysql-bin.000001

-rw-rw----. 1 mysql mysql       19 Dec 15 14:19 mysql-bin.index

-rw-r-----. 1 mysql root     17728 Dec 15 14:19 mysql-master.err

-rw-rw----. 1 mysql mysql        5 Dec 15 14:19 mysql-master.pid

drwx------. 2 mysql root      4096 Dec 13 15:07 test

drwx------. 2 mysql mysql     4096 Dec 14 16:34 xiaoyi


mysql> show variables like 'log_bin';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| log_bin       | ON    |

+---------------+-------+

1 row in set (0.00 sec)


mysql> show variables like 'server_id';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| server_id     | 2    |

+---------------+-------+

1 row in set (0.00 sec)



(3)建立用於同步的帳號rep

mysql> grant replication slave on *.* to 'rep'@'192.168.11.%' identified by "rinimei";

Query OK, 0 rows affected (0.00 sec)


mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)


#replication slave爲mysql同步的必須權限,此處不要授權all

#*.*表示所有庫所有表,也可以指定具體的庫和表進行復制。xiaoyi.test

#'rep'@'192.168.11.%',rep爲同步帳號, 192.168.11.%爲授權主機網段,使用了%表示允許整個192.168.11.0網段以rep用戶訪問

mysql>flush tables with read lock;

查看主庫狀態

mysql>show master status;

show master logs;

再開一個窗口

mysqldump -uroot -prinimei -A -B --events --master-data=2 > /opt/rep.sql

mysql>unlock tables;



從庫操作:

mysql -uroot -prinimei < rep.sql


從庫log-bin可開可不開,從庫server-id與主庫不一樣

mysql> CHANGE MASTER TO MASTER_HOST='192.168.11. 2',MASTER_PORT=3306,MASTER_USER='rep',MASTER_PASSWORD='rinimei',MASTER_LOG_FILE='mysql-bin.000007',MASTER_LOG_POS=334;

Query OK, 0 rows affected (0.09 sec)


[root@mysql-slave data]# cat master.info 

15

mysql-bin.000007

334

192.168.11.2

rep

rinimei

3306

60

0


mysql> start slave;

Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.11.2

                  Master_User: rep

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000007

          Read_Master_Log_Pos: 334

               Relay_Log_File: mysql-slave-relay-bin.000002

                Relay_Log_Pos: 251

        Relay_Master_Log_File: mysql-bin.000007

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

mysql-master->create database zz;

Query OK, 1 row affected (0.01 sec)

mysql-slave->show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| gong               |

| gongyi             |

| mysql              |

| test               |

| xiaoyi             |

| yy                 |

| zz                 |

+--------------------+

8 rows in set (0.00 sec)



7.4 mysql主從同步配置步驟

(1)準備兩臺數據庫環境,或者單臺多實例環境,能否正常啓動和登陸

(2)配置my.cnf文件,主庫配置log-bin和server-id參數,從庫配置server-id,不能和主庫及其他從庫一樣,一般不開啓從庫log-bin功能。注意:配置參數後要重啓生效。

(3)登陸主庫增加用於從庫連接主庫同步的賬戶,例如:rep,並授權replication slave同步的權限。

(4)登陸主庫,整庫鎖表flush table with read lock(窗口關閉後失效,超時參數到了也失效),然後show master status查看binlog的位置狀態

(5)新開窗口,linux命令行備份或導出原有的數據庫數據,並拷貝到從庫所在的服務器目錄

如果數據量很大,並且允許停機,可以停機打包,而不用mysqldump

(6)解鎖主庫,unlock tables;

(7)把主庫導出的原有數據恢復到從庫

(8)根據主庫的show master status查看binlog的位置狀態,在從庫執行change master to

(9)從庫開啓同步開關 start slave

(10)從庫show slave status\G,檢查同步狀態,並在主庫進行更新測試




7.5 mysql主從故障及主從延遲解決方案

(1)MySQL數據庫主從同步延遲原理。

 

答:談到MySQL數據庫主從同步延遲原理,得從mysql的數據庫主從複製原理說起,mysql的主從複製都是單線程的操作,主庫對所有DDL和DML產生binlog,binlog是順序寫,所以效率很高,slave的Slave_IO_Running線程到主庫取日誌,效率很比較高,下一步,問題來了,slave的Slave_SQL_Running線程將主庫的DDL和DML操作在slave實施。DML和DDL的IO操作是隨即的,不是順序的,成本高很多,還可能可slave上的其他查詢產生lock爭用,由於Slave_SQL_Running也是單線程的,所以一個DDL卡主了,需要執行10分鐘,那麼所有之後的DDL會等待這個DDL執行完纔會繼續執行,這就導致了延時。有朋友會問:“主庫上那個相同的DDL也需要執行10分,爲什麼slave會延時?”,答案是master可以併發,Slave_SQL_Running線程卻不可以。

 

(2) MySQL數據庫主從同步延遲是怎麼產生的。

 

答:當主庫的TPS併發較高時,產生的DDL數量超過slave一個sql線程所能承受的範圍,那麼延時就產生了,當然還有就是可能與slave的大型query語句產生了鎖等待。

 

(3) MySQL數據庫主從同步延遲解決方案

 

答:最簡單的減少slave同步延時的方案就是在架構上做優化,儘量讓主庫的DDL快速執行。還有就是主庫是寫,對數據安全性較高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不需要這麼高的數據安全,完全可以講sync_binlog設置爲0或者關閉binlog,innodb_flushlog也可以設置爲0來提高sql的執行效率。另外就是使用比主庫更好的硬件設備作爲slave。

 

mysql-5.6.3已經支持了多線程的主從複製。Oracle使用的是以數據庫(schema)爲單位做多線程,不同的庫可以使用不同的複製線程。

 

sync_binlog=1

 

This makes MySQL synchronize the binary log’s contents to disk each time it commits a transaction

 

默認情況下,並不是每次寫入時都將binlog與硬盤同步。因此如果操作系統或機器(不僅僅是MySQL服務器)崩潰,有可能binlog中最後的語句丟 失了。要想防止這種情況,你可以使用sync_binlog全局變量(1是最安全的值,但也是最慢的),使binlog在每N次binlog寫入後與硬盤 同步。即使sync_binlog設置爲1,出現崩潰時,也有可能表內容和binlog內容之間存在不一致性。如果使用InnoDB表,MySQL服務器 處理COMMIT語句,它將整個事務寫入binlog並將事務提交到InnoDB中。如果在兩次操作之間出現崩潰,重啓時,事務被InnoDB回滾,但仍 然存在binlog中。可以用--innodb-safe-binlog選項來增加InnoDB表內容和binlog之間的一致性。(註釋:在MySQL 5.1中不需要--innodb-safe-binlog;由於引入了XA事務支持,該選項作廢了),該選項可以提供更大程度的安全,使每個事務的 binlog(sync_binlog =1)和(默認情況爲真)InnoDB日誌與硬盤同步,該選項的效果是崩潰後重啓時,在滾回事務後,MySQL服務器從binlog剪切回滾的 InnoDB事務。這樣可以確保binlog反饋InnoDB表的確切數據等,並使從服務器保持與主服務器保持同步(不接收 回滾的語句)。

 

 

抱怨Innodb比MyISAM慢 100倍?那麼你大概是忘了調整這個值。默認值1的意思是每一次事務提交或事務外的指令都需要把日誌寫入(flush)硬盤,這是很費時的。特別是使用電 池供電緩存(Battery backed up cache)時。設成2對於很多運用,特別是從MyISAM錶轉過來的是可以的,它的意思是不寫入硬盤而是寫入系統緩存。日誌仍然會每秒flush到硬 盤,所以你一般不會丟失超過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL掛了也可能會丟失事務的數據。而值2只會在整個操作系統 掛了時纔可能丟數據。




7.6 mysql主從常見故障

主從複製部署配置問題彙總:

(1)主庫show master status沒結果,主庫binlog功能開關沒開或沒生效

egrep "server-id|log-bin" /etc/my.cnf

log-bin = mysql-bin

server-id = 1


mysql>show variables like 'server_id';

mysql>show variables like 'log_bin';

提示:配置文件裏的參數和show variables裏的參數不一樣,例如my.cnf裏log-bin,show的時候log_bin


mysql5.1 flush tables with read lock;

mysql5.5 flush table with read lock;

提示:這個鎖表命令的時間,在不同的引擎的情況下,會受下面參數的控制,鎖表時,如果超過設置時間不操作會自動解鎖

interactive_timeout = 60

wait_timeout = 60

默認情況下時長爲:

mysql>show variables like '%timeout%';

set global wait_timeout = 10;

set global interactive_timeout = 10;


(2)CHANGE MASTER時多了空格錯誤:

Last_IO_Error:Got fatal error 1236 from master when reading data from binary log:'Could not find first log file name in binary log index file'

MASTER_LOG_FILE=' mysql-bin.000001 ';

(3)服務無法啓動故障

/etc/init.d/mysqld start

MYSQL is running

ps -ef|grep mysql

root163615950 11:47 pts/000:00:00 grep --color=auto mysql

rm -f /application/mysql/mysql.sock /application/mysql/*.pid

/etc/init.d/mysqld start


(4)由於切換binlog導致show master status位置變化無影響



7.7 mysql主從複製線程狀態

登陸數據庫查看mysql線程同步狀態

主庫/從庫

mysql>show processlist\G

    下面列出了主服務器binlog dump線程的state列的最常見的狀態。

sending binlog event to slave

二進制日誌由各種事件組成,一個事件通常爲一個更新加一些其他信息。線程已經從二進制日誌讀取了一個事件並且正將它發送到從服務器。

finished reading one binlog;switching to next binlog

線程已經讀完二進制日誌文件並且正打開下一個要發送到從服務器的日誌文件

has sent all binlog to slave;waiting for binlog to be updated

線程已經從二進制日誌讀取所有主要的更新並已經發送到了從服務器。線程現在正空閒,等待由主服務器上新的更新導致的出現在二進制日誌中的新事件

waiting to finalize termination

線程停止事發生的一個很簡單的狀態


複製從I/O線程狀態

    下面列出了從服務器的I/O線程的state列的最常見的狀態。該狀態也出現在Slave_IO_State列,由SHOW SLAVE STATUS顯示。


connecting to master

線程正試圖連接主服務器

checking master version

建立同主服務器之間的連接後立即臨時出現的狀態

registering slave slave on master

建立同主服務器之間的連接後立即臨時出現的狀態

requesting binlog dump

建立同主服務器之間的連接後立即臨時出現的狀態。線程向主服務器發送一條請求,索取從請求的二進制日誌文件名和位置開始的二進制日誌的內容

waiting to reconnect after a failed binlog dump request

線程正嘗試重新連接主服務器

waiting for master to send event

線程已經連接上主服務器,正等待二進制日誌事件到達。如果主服務器正空閒,會持續較長的事件。如果等待持續slave_read_timeout秒,則發生超時。此時,線程認爲連接被中斷並企圖重新連接。

queueing master event to the relay log

線程已經讀取一個事件,正將它複製到中繼日誌供SQL線程來處理

waiting to reconnect after a failed mster event read

讀取時(由於沒有連接)出現錯誤。線程企圖重新連接前將睡眠master-connect-retry秒

reconnecting after a failed master event read

線程正嘗試重新連接主服務器。當連接重新建立後,狀態變爲waiting for master to send

waiting for the slave SQL thread to free enough relay log space

正使用一個非零relay_log_space_limit值,中繼日誌已經增長到其組合大小超過該值。I/O線程正等待直到SQL線程處理中繼日誌內容並刪除部分中繼日誌文件來釋放足夠的空間。

waiting for slave mutex on exit

線程停止時發生的一個很簡單的狀態。



複製從SQL線程狀態

    下面列出了從服務器的SQL線程的state列的最常見的狀態。

reading event from the relay log

線程已經從中繼日誌讀取一個事件,可以對事件進行處理了

has read all relay log;waiting for the slave I/O thread to update it

線程已經處理了中繼日誌文件中的所有事件,現在正等待I/O線程將新事件寫入中繼日誌

waiting for slave mutex on exit

線程停止時發生的一個很簡單的狀態。

I/O線程的state列也可以顯示語句的文本。這說明線程已經從中繼日誌讀取了一個事件,從中提取了語句,並且正在執行語句。


查看mysql線程同步狀態的用途

    通過mysql線程同步狀態查看數據庫同步是否完成,用於主庫宕機或者人工數據庫主從切換遷移等。

    主機宕機選擇最快的從庫提升爲主,就需要查看,當然也可以利用mysql的半同步功能,選擇固定的庫提升爲主。


7.8 mysql主從讀寫分離授權方案

(1)方案1

主庫:web rinimei 192.168.11.2 3306(select,insert,delete,update)

從庫:主庫的web用戶同步到從庫,然後回收insert,delete,update權限


(2)方案2

主庫:web _w rinimei 192.168.11.2 3306 (select,insert,delete,update)

從庫:web_r rinimei 192.168.11.3 3306 (select)

風險:web_w連接從庫

開發:2套用戶密碼不專業


3.方案3

mysql庫不同步binlog-igore-db=mysql

主庫:web rinimei 192.168.11.2 (select,insert,delete,update)

從庫:web rinimei 192.168.11.3(select)

缺陷:從庫切換主庫的時候,連接用戶權限問題

保留一個從庫專門準備接替主


4.方案4

設置從庫read-only


生產環境一般採取忽略授權表方式的同步,然後對從服務器slave上的用戶僅授權select讀權限。不同步mysql庫,這樣我們就保證主庫和從庫相同的用戶可以授權不同的權限。


replicate-ignore-db = mysql

binlog-ignore-db = mysql

binlog-ignore-db = performance_schema

binlog-ignore-db = information_schema


DO:同步少量庫

binlog-do-db=db_xiaoyi

replicate-do-db=db_xiaoyi   #如需跨數據庫更新並且不想複製這些更新,應該使用該選項

replicate-do-table=db_xiaoyi #允許跨數據庫更新

replicate-wild-do-table=db_xiaoyi #用於跨數據庫更新


ignore:排除

binlog-ignore-db=mysql

replicate-ignore-db=mysql  #如需跨數據庫更新並且不想複製這些更新,不應使用該選項

replicate-ignore-table=mysql #該選項可以跨數據庫進行更新

replicate-wild-ignore-table=db_xiaoyi #該選項可以跨數據庫進行更新。


特殊注意:

如果服務器用binlog-ignore-db=sales啓動,並且執行USE prices;UPDATE sales.januar SET amount=amount+1000;該語句不寫入二進制日誌。



Replication中還以通過以下選項來減少binlog數據量,

來達到提高效率的目的,前兩個用在Master端,後六個是用在Slave端


Master端:

--binlog-do-db二進制日誌記錄的數據庫(多個數據庫用,分隔)

--binlog-ignore-db二進制日忽略的數據庫(多個數據庫用,分隔)


在replication的slave端還有以下6個參數

--replication-do-db設定需要複製的數據庫(多個數據庫用,分隔)

--replication-ignore-db設定忽略複製的數據庫(多個數據庫用,分隔)

--replication-do-table設定需要複製的表(多個表用,分隔)

--replication-ignore-table設定忽略複製的表(多個表用,分隔)

--replication-wild-do-table同replication-do-table功能一樣,但是可以加通配符

--replication-wild-ignore-table同replication-ignore-table功能一樣,但是可以加通配符


mysql連接慢:

skip-name-resolve


讓mysql slave庫記錄binlog方法


需要記錄binlog的情況

1.當前從庫還要作爲其他從庫的主庫

2.把從庫作爲備份服務器時需要開啓binlog


log-bin = mysql-bin

log-slave-updates

expire_logs_days = 7



7.9 mysql雙主方案

解決主鍵自增長變量衝突:

master1:

auto_increment_increment = 2 #自增ID的間隔,如1 3 5間隔爲2

auto_increment_offset = 1 #ID的初始位置

(將形成1,3,5,7...序列)

master2:

auto_increment_increment = 2 #自增ID的間隔,如2 4 6間隔爲2

auto_increment_offset = 2 #ID的初始位置

(將形成2,4,6,8...序列)


1,3,5       11

     6,8,10


mysqldump -uroot -prinimei -A -B --master-date=1 -x --events > /opt/bak.sql

change master to


create table student(

id int(4) not null AUTO_INCREMENT,

name char(20) not null,

primary key(id)

);


insert into student(name) values('xiaoyi1');



互爲主從參數:

log-slave-updates #開啓從庫binlog日誌

binlog-ignore-db=mysql #不記錄binlog日誌

skip-slave-start #啓動時忽略從庫啓動

replicate-same-server-id = 0


#########以下爲在主庫master1(10.0.0.240 3306)上的操作

1.開啓binlog並設置server-id的值

vim /etc/my.cnf

server-id = 247 #IP最後一位數字的前兩個數字 加 端口號數字的最後一位

log-bin=mysql-bin


2.建立用於同步的帳號ryanrep(master)

mysql -uroot -prinimei 

grant replication slave on *.* to 'ryanrep'@'10.0.0.%' identified by 'ryanrep';


3.鎖表只讀(master)(切記窗口不要關掉)

flush tables with read lock;


4.查看master狀態當前日誌文件名和二進制日誌偏移量(要記錄,後面要用到)

mysql> show master status;

+------------------+----------+--------------+------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000003 |     1323 |              |                  |

+------------------+----------+--------------+------------------+

1 row in set (0.00 sec)


5.單開新窗口,備份數據庫(數據量大,並且允許停機可以TAR,或直接CP)(master)

mysqldump -uroot -prinimei -A -B >/home/rhy/from240.sql



雙主同步,互爲主從

#m1(10.0.0.240 3306)

#____m-m m1 start____

auto_increment_increment = 2

auto_increment_offset = 1

log-slave-updates

log-bin

#m2(10.0.0.242 3306)

#____m-m m2 start____

auto_increment_increment = 2

auto_increment_offset = 2

log-slave-updates

log-bin


使用主主前提:

1.表的主鍵自增

2.程序寫庫指定ID



八、mysql服務多種日誌

8.1 mysql三種常見日誌類型

錯誤日誌(error log):記錄mysql服務進程mysqld在啓動/關閉或運行過程中遇到的錯誤信息:

查詢日誌(uery log):又可分爲兩類

    普通查詢日誌(general query log):記錄客戶端連接信息和執行的SQL語句信息

    慢查詢日誌(slow query log):記錄執行時間超出指定值(lang_query_time)的SQL語句

二進制日誌(binary log):記錄數據被修改的相關信息


錯誤日誌:

[mysqld_safe]

log-error = mysql.err

普通查詢日誌:

show variables like 'general_log%';

慢查詢日誌:

lang_query_time = 1

log-slow-queries = slow.log

log_queries_not_using_indexes

二進制日誌

mysql> show variables like '%log_bin%';

+---------------------------------+-------+

| Variable_name                    | Value |

+---------------------------------+-------+

| log_bin                         | ON    |    記錄binlog

| log_bin_trust_function_creators     | OFF   |    臨時不記錄binlog

| sql_log_bin                      | ON    |

+---------------------------------+-------+

3 rows in set (0.00 sec)


8.2 binlog日誌的三種模式

statement level模式

    每一條會修改數據的sql都會記錄到master的bin-log中。slave在複製的時候sql進程會解析成和原來master端執行過的相同的sql來再次執行。

    優點:statement level下的優點首先就是解決了row level下的缺點,不需要記錄每一行數據的變化,減少bin-log日誌量,節約IO,提高性能。因爲他只需要記錄在Master 上所執行的語句的細節,減少bin-log日誌量,節約IO,提高性能。因爲它只需要記錄在master上所執行的語句的細節,以及執行語句時候的上下文的信息

    缺點:由於是記錄的執行語句,所以,爲了讓這些語句在slave端也能執行,還必須記錄每條語句在執行的時候的一些相關信息,也就是上下文信息,以保證所有語句在slave端被執行的時候能夠得到和在master端執行時候相同的結果。


Row Level模式

    日誌中會記錄成每一行數據被修改的形式,然後在slave再對相同的數據進行修改。

    優點:在row level模式下,bin-log中可以不記錄執行的sql語句的上下文相關的信息,僅僅只需記錄那一條記錄被修改了。所以row level的日誌內容會非常清楚的記錄下每一行數據修改的細節,非常容易理解。

    缺點:row level模式下,所有的語句當記錄到日誌中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日誌內容。


Mixed模式

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


8.3 調整binlog日誌模式方法

(1)在配置文件中修改

log-bin = mysql-bin

binlog_format = "STATEMENT"

binlog_format = "ROW"

binlog_format = "MIXED"

(2)在線修改立即生效方法

運行時在線修改:

mysql>set session binlog_format = 'STATEMENT';

mysql>set session binlog_format = 'ROW';

mysql>set session binlog_format = 'MIXED';

(3)全局生效:

mysql>set global binlog_fomat = 'STATEMENT';

mysql>set global binlog_fomat = 'ROW';

mysql>set global binlog_fomat = 'MIXED';



九、mysql存儲引擎

9.1什麼是存儲引擎

    數據庫表裏的數據存數在數據庫裏與mp4 .avi等文件存儲在磁盤上類似。

    對於用戶和應用程序來說同樣一張表的數據,無論用什麼引擎來存儲,用戶看到的數據都是一樣的。不同的引擎存儲,引擎的功能,佔用的空間大小,讀取性能可能有區別。

    mysql最常用的存儲引擎爲:Myisam和Innodb。



9.2 mysql事務以及ACID特性

    簡單的說,事務就是指邏輯上一組SQL語句操作,組成這組操作的各個SQL語句,執行時要麼全成功要麼全失敗。


事務的四大特性(ACID)

a.原子性(Atomicity)

事務是一個不可分割的單位,事務中的所有SQL等操作要麼全都發生,要麼都不發生。

b.一致性(Consistency)

事務發生前和發生後,數據的完整性必須保持一致

c.隔離性(Isolation)

當併發訪問數據庫時,一個正在執行的事務在執行完畢前,對於其他的會話是不可見的,多個併發事務之間的數據是相互隔離的。

d.持久性(Durability)

一個事務一旦被提交,它對數據庫中的數據改變就是永久性的。如果出了錯誤,事務也不允許被撤銷,只能通過“補償性事務”。


事務的開啓:

數據庫默認事務是自動提交的,也就是發一條sql它就執行一條。如果想多條sql放一個事務中執行,則需要使用事務進行處理。當開啓一個事務,並且沒有提交,mysql會自動回滾事務。或者使用rollback手動回滾事務。


數據庫開啓事物命令:

start transcation 開啓事務

rollback 回滾事務

commit提交事務


set global autocommit=OFF;

set autocommit=OFF禁止自動提交

set autocommit=ON開啓自動提交

rollback 回滾事物

commit提交事物



9.3 MyISAM引擎特點及調優

MyISAM引擎特點

(1)不支持事務

(2)表級鎖定(更新時鎖整個表);其鎖定機制是表級索引,這雖然可以讓鎖定的實現成本很小但是也同時大大降低了其併發性能。

(3)讀寫互相阻塞:不僅會在寫入的時候阻塞讀取,MyISAM在讀的時候阻塞寫入,但本身讀不會阻塞另外的讀。

(4)只會緩存索引:MyISAM可以通過key_buffer_size緩存索引,以大大提高訪問性能減少磁盤IO,但是這個緩存區只會緩存所引,而不會緩存數據。

(5)讀取速度較快,佔用資源相對較少。

(6)不支持外鍵約束,但支持全文索引。

(7)MyISAM引擎是MySQL5.5.5前缺省的存儲引擎


MyISAM引擎適用的場景

(1)不需要事務支持的業務(轉賬就不行)

(2)一般爲讀數據比較多的應用,讀寫都頻繁場景不適合,讀多或者寫多的都適合。

(3)讀寫併發訪問相對較低的業務(純讀純寫高併發也可以)

(4)數據修改相對較少的業務(阻塞問題)

(5)以讀爲主的業務

(6)對數據一致性要求不是非常高的業務。

(7)硬件資源比較差的機器可以用MyISAM

小結:單一對數據庫的操作都可以使用MyISAM,所謂單一就是儘量純讀,或純寫


MyISAM引擎調優

(1)設置合適的索引(緩存機制)

(2)調整讀寫優先級,根據實際需求確保重要操作更優先執行。

(3)啓用延遲插入改善大批量寫入性能(降低寫入頻率,儘可能多條數據一次性寫入)

(4)儘量順序操作讓insert數據都寫入到尾部,減少阻塞。

(5)分解大的操作,降低單個操作的阻塞時間。

(6)降低併發數(減少對mysql訪問),某些高併發場景通過應用進行排隊隊列機制

(7)對於相對靜態(更改不頻繁)的數據庫數據充分利用Query Cache或memcached緩存服務可以極大的提高訪問效率。

query_cache_size = 2M

query_cache_limit = 1M

query_cache_min_res_unit = 2k

(8)MyISAM的Count只有在全表掃描的時候特別高效,帶有其他條件的count都需要進行實際的數據訪問。

select count(*) from test.table;

(9)可以把主從同步的主庫使用innodb,從庫使用MyISAM引擎



9.4 InnoDB引擎特點及調優

(1)支持事務:支持4個事務隔離級別,支持多版本讀

(2)行級鎖定(更新時一般是鎖定當前行)通過索引實現,全表掃描仍然會是表鎖,注意間隙鎖的影響。

(3)讀寫阻塞與事務隔離級別相關

(4)具有非常高效的緩存特性:能緩存索引,也能緩存數據

(5)整個表和主鍵以Cluster方式存儲,組成一顆平衡樹。

(6)所有Secondary Index都會保存主鍵信息

(7)支持分區,表空間,類似oracle數據庫

(8)支持外鍵約束,5.5以前不支持全文索引,以後支持了

(9)和MyISAM引擎比,InnoDB對硬件資源要求比較高。



InnoDB引擎適合的場景

(1)需要事務支持的業務(具有較好的事務特性)

(2)行級鎖定對高併發有很好的適應能力,但需要確保查詢是通過所引完成。

(3)數據讀寫及更新都較爲頻繁的場景,如:BBS,SNS,微博,微信等。

(4)數據一致性要求高的業務,例如:充值轉賬,銀行卡轉賬。

(5)硬件設備內存較大,可以利用InnoDB較好的緩存能力來提高內存利用率,儘可能減少磁盤IO。


InnoDB引擎調優

(1)主鍵儘可能小,避免給Secondary index帶來過大的空間負擔

(2)避免全表掃描,因爲會使用表鎖

(3)儘可能緩存所有的所引和數據,提高相應速度,減少磁盤IO消耗

(4)在大批量小插入的時候,儘量自己控制事務而不要使用autocommit自動提交。有開關可以控制提交方式

(5)合理設置innodb_flush_log_at_trx_commit參數值,不要過度追求安全性。

如果innodb_flush_log_at_trx_commit的值爲0,log buffer每秒就會被刷寫日誌文件到磁盤,提交事務的時候不做任何操作。

(6)避免主鍵更新,因爲這就會帶來大量的數據移動。



InnoDB引擎重要參數:

innodb_additional_mem_pool_size = 16M

innodb_buffer_pool_size = 2048M  (50%-80%)

innodb_data_file_path = ibdata1:1024M:autoextend

innodb_file_io_threads = 4

innodb_thread_concurrency = 8

innodb_flush_log_at_trx_commit = 2

innodb_log_buffer_size = 16M

innodb_log_file_size = 128M

innodb_log_files_in_group = 3

innodb_max_dirty_pages_pct = 90

innodb_lock_wait_timeout = 120

innodb_file_per_table = 0


MyISAM引擎重要參數

key_buffer_size = 2048M



9.5修改mysql引擎

(1)mysql命令語句修改

ALTER TABLE test ENGINE = MyISAM


(2)使用sed對備份內容進行引擎轉換

mysqldump >aa.sql

nohup sed -e 's/MyISAM/InnoDB/g' aa.sql  > bb.sql &

mysql <bb.sql


(3)mysql_convert_table_format命令修改

mysql_convert_table_format --user=root --password=rinimei --engine=MyISAM xiaoyi test;



十、mysql優化

10.1 mysql負載高情況查看

(1)系統負載比較高

uptime

(2)網站打開很慢,mysql大量線程等待

mysql -uroot -prinimei -e "show full processlist"|grep -vi sleep

(3)慢查詢語句

long_query_time = 1

log-slow-queries = slow.log


查看利用索引情況

explain select id from test where ader='' and dateline='';

查看錶結構

show create table test \G


10.2 mysql優化思路

(1)從業務上實現用戶先登錄後再搜索,這樣減少搜索次數,從而減輕數據庫的壓力

(2)如果有大量頻繁的搜索,一般是爬蟲在爬網站,分析web日誌(AWTATS),封IP

(3)配置多個主從同步,程序上實現讀寫分離

(4)在數據庫前端加上memcacehd緩存

(5)like '%666%'的語句,一般在mysql裏很難優化,可以通過搜索服務Sphinx實現搜索


10.3 mysql數據庫優化

(1)硬件優化

a.64位CPU 一臺機器8-16顆CPU 2-4顆

b.mem 96G-128G 3-4個實例 32G-64G 2個實例

c.disk 數量越多越好 性能:SSD(高併發)>SAS(普通業務線上)>SATA(線下)

 raid 4塊盤:RAID0>RAID10>RAID5>RAID1

d. 多快網卡bond,以及buffer,tcp優化


(2)軟件優化

操作系統:x86_64系統

軟件:mysql編譯優化


(3)my.cnf參數優化

優化的幅度很小,大部分是架構以及SQL語句優化


(4)SQL語句優化

a.抓出慢查詢語句

(set global long _query_time=2;

set global slow_query_log='ON';)

my.cnf

long_query_time = 2

long-slow-queries = /usr/local/mysql/mysql-slow.log

log-queries-not-using-indexes = on 

按天輪訓slow.log

b.慢查詢日誌分析工具 mysqlsla

c.大的複雜的SQL語句拆成多個小的SQL語句

d.數據庫是存儲數據的地方,不是計算數據的地方,對數據計算,應用類處理,都要拿出


(5)架構上優化

a.業務拆分:搜索功能,like '666'一般不要用mysql;交友等業務使用nosql持久化存儲

b.數據庫前端加緩存,memcacehd等

c.動態的數據靜態化,文件,頁面靜態化(僞靜態)

d.數據庫集羣與讀寫分離。通過程序或者dbproxy進行集羣讀寫分離。


(6)流程制度安全優化

任何一次人爲數據庫記錄的更新,都要走一個流程:

a.人的流程:開發→核心開發→運維或DBA

b.測試流程:開發環境測試→測試環境測試→IDC測試→線上執行

c.客戶端管理,phpmyadmin


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章