MySQL的優化和維護


MySQL的root密碼忘記和用戶權限問題

1 MySQL的root修改密碼和忘記密碼的問題

1.1 MySQL的登錄問題:

可以使用mysql -uroot p123來登錄MySQL,但是這樣不好,會使MySQL的密碼在歷史記錄中出現,我們最好使用

mysql -uroot -p

Password:

專業就會防止MySQL密碼記錄在history中

我們也可以在命令行使用下面的命令:

HISTCONTROL=ignorespace #不記錄敏感的命令,這樣會臨時生效,你可以在/etc/profile中進行配置,讓其永久生效

 

但是在敏感的命令前加一個空格執行,那么history就不會記錄該條命令,

 

 

1.2 MySQL的服務進程啟動和停止問題

如果在單例模式下,

啟動:

/etc/init.d/mysql start

使用/etc/init.d/mysqld stop 就可以關閉

或者使用root的用戶名和密碼進行關閉MySQL服務

 mysqladmin -uroot -p123 shutdown

前兩種方法推薦使用,如果前兩種方法無法使用,使用

pkill mysql 來結束MySQL的服務進程

 

多實例模式下,

啟動:

/data/3306/mysql start

 

/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/data/${port}/my.cnf 2>&1 > /dev/null &

 

停止:

/data/3306/mysql stop #等學到了shell編程,自己去看mysql腳本

 

${CmdPath}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /data/${port}/mysql.sock shutdown

 

1.3單例情況下,MySQL的root密碼忘記情況

在這之前先說一下,如何修改用戶密碼的情況,下面的MySQL的命令都是已經在環境變量配置好的

修改用戶密碼(在知道用戶密碼的情況下):舊的密碼為123,修改新的密碼為456

A) mysqladmin -uroot -p123 password '456'

B) 進入MySQL中,使用SQL來修改用戶的密碼:

首先查看一下root用戶的密碼,看一下,發現是加密的。

mysql> select user,host,password from mysql.user;

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

| user | host      | password                                  |

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

| root | localhost | *531E182E2F72080AB0740FE2F2D689DBE0146E04 |

| root | 127.0.0.1 |                                           |

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

 

我們使用SQL修改如下:

 update mysql.user set passwod='123' where user='root' and host='localhost'

我們在查看一下新的密碼:

mysql> select user,host,password from mysql.user;                                

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

| user | host      | password |

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

| root | localhost | 123      |

| root | 127.0.0.1 |          |

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

2 rows in set (0.00 sec)

 

發現密碼沒有加密,我們執行: flush privileges;來刷新權限,但是發現在客戶端使用:mysql -uroot -p123無法登錄

原因:客戶端獲取密碼以后,先用算法加密,在與數據庫中的密碼進行比對,所以數據庫里面的的密碼123是加密以后的密碼,所以我們需要對明文的‘123’進行加密,如何設置呢?

其實只有把上面的修改密碼的SQL語句修改一下即可:

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

在查詢一下用戶密碼:

 

mysql> select user,host,password from mysql.user;                                            

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

| user | host      | password                                  |

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

| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |

| root | 127.0.0.1 |                                           |

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

2 rows in set (0.00 sec)

 

發現密碼已經加密,在執行flush privileges;刷新權限,就可以登錄了

 

 

多實例的情況下,在使用MySQL命令授權的時候,需要指定一下多實例的sock文件

下面是具體的命令:

 

 

1.4 學會使用MySQL的幫助

登錄MySQL,在MySQL中,如果對命令什么的不清楚,可以使用 COMMAND HELP

例如,如果對create命令不清楚,可以使用

mysql> help create

Many help items for your request exist.

To make a more specific request, please type 'help <item>',

where <item> is one of the following

topics:

   CREATE DATABASE

   CREATE EVENT

   CREATE FUNCTION

   CREATE FUNCTION UDF

   CREATE INDEX

   CREATE LOGFILE GROUP

   CREATE PROCEDURE

   CREATE SERVER

   CREATE TABLE

   CREATE TABLESPACE

   CREATE TRIGGER

   CREATE USER

   CREATE VIEW

   SHOW

   SHOW CREATE DATABASE

   SHOW CREATE EVENT

   SHOW CREATE FUNCTION

   SHOW CREATE PROCEDURE

   SHOW CREATE TABLE

   SPATIAL

 

在對你需要的create xxx help,例如你想知道如果create database,你可以使用

Help CREATE DATABASE,you will find hwo to use this command.

 

mysql> help CREATE DATABASE

Name: 'CREATE DATABASE'

Description:

Syntax:

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name

    [create_specification] ...

 

create_specification:

    [DEFAULT] CHARACTER SET [=] charset_name

  | [DEFAULT] COLLATE [=] collation_name

 

CREATE DATABASE creates a database with the given name. To use this

statement, you need the CREATE privilege for the database. CREATE

SCHEMA is a synonym for CREATE DATABASE.

 

URL: http://dev.mysql.com/doc/refman/5.1/en/create-database.html

1.5 root密碼忘記

單實例的情況下:

如果MySQL的root密碼忘記了,首先我們需要停止MySQL的服務.關於如何停止MySQL服務進程,在什么已經介紹了,現在就不重復敘述了。

然后使用忽略用戶授權的方法來啟動MySQL的服務進程,具體的命令如下:

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

但是在二進制解壓安裝的機器上會出現問題,所以我們在多實例的機器上進行測試(多實例MySQL是編譯安裝的,在實際企業中,是先使用編譯安裝,然后把編譯安裝的做成rpm包,然后在批量的安裝)

如果在多實例的機器上測試,那么就需要增加一個配置文件

mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-table

然后你使用

ss -lntup|grep 330,你將會發現3306的端口已經啟動了,你在用登錄的命令就可以登錄MySQL客戶端了。

mysql -S /data/3306/mysql.sock

 

然后進去修改root密碼,使用什么說過的update語句

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

然后刷新權限( flush priviliges;)。此時密碼以及修改成功。我們需要

退出客戶端,使用kill 命令來殺死MySQL進程,在用正常的方式來啟動MySQL服務進程(/data/3306/mysql start),使用新密碼即可重新登錄( mysql -uroot -p123 -S /data/3306/mysql.sock )

 

1.6 MySQL的默認字符集以及如果設置數據庫的字符集

如果在編譯的時候設置了MySQL的字符集,那么在創建數據庫和數據表時不特定指定MySQL的字符集,那么使用的就是默認的字符集來創建數據庫和數據表

我們用下面的命令來查看一個數據庫或者數據表使用的是什么樣的字符集

mysql> show create database 3306d\G

 

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

       Database: 3306d

Create Database: CREATE DATABASE `3306d` /*!40100 DEFAULT CHARACTER SET utf8 */

1 row in set (0.06 sec)

可以看的出來,使用的是utf8的字符集,是因為在編譯的時候指定的,不然編譯的時候不指定,那么默認是拉丁(latin1)

 

那么我們如何創建指定字符集的數據庫或者數據表呢?

 

create database yghdb1 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; #指定數據的格式為gbk

 

#查看是否為gbk

mysql> show create database yghdb1\G                                           

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

       Database: yghdb1

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

 

create database yghdb2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; #指定編碼為utf8

 

 

 

1.7 創建用戶和授權

在數據庫中,為是數據安全,我們一般對不使用root用戶來登錄數據庫,只使用普通用戶去連接他可以管理的數據庫,因此我們創建普通用戶和給其授權。

 

第一種方法,先創建,在授權

創建用戶使用下面的命令:

create user 'ygh1'@'localhost' identified by '123';

用戶名和主機 密碼

 

上面的命令僅僅是創建了一個用戶,該用戶不具備任何權限,只能登錄數據庫,無法進入和查詢沒有權限的數據庫。

下面給剛才創建的用戶進行授權:

GRANT ALL ON yghdb1.* TO 'ygh1'@'localhost';

通用的寫法

GRANT privileges ON daname.tablename TO 'username'@'host';

查看具體用戶的權限使用下面的命令:

mysql> show grants for 'ygh1'@'localhost';

 

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

| Grants for ygh1@localhost                                                                                   |

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

| GRANT USAGE ON *.* TO 'ygh1'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |

| GRANT ALL PRIVILEGES ON `yghdb1`.* TO 'ygh1'@'localhost'                                                    |

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

2 rows in set (0.00 sec)

 

第二種方式,授權並創建用戶

GRANT ALL PRIVILEGES ON yghdb2.* TO 'ygh2'@'localhost' IDENTIFIED BY '123';

通用的寫法:

GRANT ALL PRIVILEGES ON dbName.tableName TO 'username'@'host' IDENTIFIED BY 'password';

 

查看ygh2的用戶權限:

mysql> SHOW GRANTS FOR ygh2@localhost;

 

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

| Grants for ygh2@localhost                                                                                   |

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

| GRANT USAGE ON *.* TO 'ygh2'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |

| GRANT ALL PRIVILEGES ON `yghdb2`.* TO 'ygh2'@'localhost'                                                    |

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

2 rows in set (0.00 sec)

 

查看所有用戶的對數據庫和表的權限:

 select *from mysql.user\G;

\G是為了顯示好看一點。

 

1.8 如果移除用戶的某些權限

在數據庫中,我們為了安全起見,給用戶的權限應該滿足用戶的需求即可,不能給太大的權限。

那我們如果去撤銷用某些特權,例如撤銷用戶ygh2的insert權限。

首先查看一下ygh2對哪些數據庫有哪些權限。

 GRANT USAGE ON *.* TO 'ygh2'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |

 

#上面的表示ygh2只是一個普通用戶,對*.*(所有的數據庫和表沒有任何權限),

USAGE 表示沒有任何權限,只能登錄。

 

| GRANT ALL PRIVILEGES ON `yghdb2`.* TO 'ygh2'@'localhost'  

#上面的說明給ygh2對yghdb2的權限  

 

使用下面的命令撤銷ygh2對yghdb2的insert權限:

REVOKE INSERT ON yghdb2.* FROM 'ygh2'@'localhost';

 

通用的方法寫法:

REVOKE privileges ON dbname.tableName FROM 'username'@host;

 

我們在查看一下ygh2對yghdb2的權限

 

mysql> show grants for 'ygh2'@'localhost';               

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

| Grants for ygh2@localhost                                                                                                                                                                                                      |

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

| GRANT USAGE ON *.* TO 'ygh2'@'localhost' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'                                                                                                                    |

| 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 `yghdb2`.* TO 'ygh2'@'localhost' |

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

2 rows in set (0.00 sec)

 

由此我們可以得出用戶在數據庫中權限有:

 

  1  SELECT

  2  INSERT

  3  UPDATE

  4  DELETE

  5  CREATE

  6  DROP

  7  REFERENCES

  8  INDEX

  9  ALTER

 10  CREATE TEMPORARY TABLES

 11  LOCK TABLES

 12  EXECUTE

 13  CREATE VIEW

 14  SHOW VIEW

 15  CREATE ROUTINE

 16  ALTER ROUTINE

 17  EVENT

 18  TRIG

 

對於一開始網站的測試和架構階段,我們可以給較大的權限,后來網站正常運行,我們值給網站基本的權限(SELECT,INSERT,UPDATA,DELETE).

 

 

注:在Linux命令行也可以不進行MySQL而執行MySQL里面的命令

mysql -uroot -p123 -S /data/3306/mysql.sock -e 'show grants for 'ygh2'@'localhost';'

通用寫法:4

mysql -uroot -p123 -S /data/3306/mysql.sock -e 'MYSQL COMMAND'

 

 

1.9 如果設置MySQL的用戶的遠程登錄

設置MySQL的用戶還可以這么進行設置,

a)使用根據IP來設置

GRANT ALL ON *.* TO test@'192.168.160.%' identified by '123';

 

通用的寫法:

GRANT PRIVILEGES ON dbName.tableName TO username@'192.168.160.%' IDENTIFIED BY 'password';

 

你在另一台機器上,使用下面的命令來進行登錄

mysql -utest -p123 -h 192.168.160.129 -P 3306

指定IP 指定端口

 

b)根據網段來設置

 

GRANT ALL ON *.* TO test2@'192.168.160.255/255.255.255.0' identified by '123';

這個我沒有測試成功,不知道為什么,但是上面的IP的是可以的。

 

2 MySQL的常用操作

2.1主鍵和索引

首先創建一張表

create table student( t_id varchar(32), t_name varchar(60), t_age int, t_dept varchar(23));

 

A):設置該表的t_id 為主(PRI)

如果在創建表的時候,可以進行這么設置

create table student( t_id varchar(32) primary key,

如果是表已經創建好了,那么可以使用下面的SQL來執行

添加已有的列作為主鍵索引:

alter table student add t_id varchar(32) primary key;

 

添加一個新的列作為主鍵索引

alter table teacher add t_id varchar(32) primary key;

 

刪除一個已經存在的主鍵索引:

alter table teacher drop primary key;

 

添加一個可重復的普通索引:

alter table student add index index_dept(t_dept);

通用的寫法

ALTER TABLE stableName ADD INDEX indexName(columName);

 

添加一個普通索引,要求把這列的前三個字符作為普通索引

alter table student add index index_name(t_name(3));

 

創建聯合索引,例如讓dept和name變為聯合索引

alter table student add index index_name_dept(t_name(3),t_dept);

聯合索引的前綴生效特性:在(abc)作為聯合索引的時候,只有abc,ab,a才會走索引。

 

 

查看一個表中的索引

desc tableName;MUL表示普通索引。

+-----+

| Key |

+-----+

| PRI |

| MUL |

|     |

| MUL |

+-----+

還有一種比較全面的方法來查看索引

show index from student\G;

 

mysql> show index from student\G;

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

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: t_id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_dept

 Seq_in_index: 1

  Column_name: t_dept

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: t_name

    Collation: A

  Cardinality: 0

     Sub_part: 3

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 4. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 1

  Column_name: t_name

    Collation: A

  Cardinality: 0

     Sub_part: 3

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 5. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 2

  Column_name: t_dept

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

5 rows in set (0.00 sec)

 

 

刪除普通索引:

alter table student drop index index_name;

通用的寫法:

ALTER TABLE tableName drop index indexName;

 

 

創建唯一索引(UNI):

alter table student drop index index_name;

 

2.2 數據庫的備份

多實例每個命令指定sock的即可

MySQL的數據的邏輯備份使用的mysqldump命令

用法:

 

2.2.1只備份數據表,不備份數據庫

也就是沒有create database和user database 的語句

mysqldump -u username -p password dbName > name.sql

 

恢復的語句:你首先需要進行數據庫,然后創建好數據庫,才能使用下面的命令

mysql -u username -p password dbName < name.sql

 

2.2.2 備份數據庫

加上-B的參數,這樣在備份的SQL腳本中,會有create database和use

Database的SQL語句

mysqldump -u username -p password -B dbName > name.sql

 

恢復語句:

mysql -u username -p password < name.sql

 

2.2.3備份並且壓縮的語句

mysqldump -u username -p password -B dbName|gzip > name.sql.gz

直接把備份的SQL腳本壓縮

 

如果使用gzip壓縮的SQL腳本,不能直接使用下面的語句進恢復

mysql -u username -p password < name.sql.gz

先使用gzip -d filename.sql;進行解壓,-d表示會刪除原來的壓縮文件

所有,對解壓后的文件要小心的保存

mysql -u username -p password < name.sql

即可完成備份數據庫

 

2.2.4 備份多個數據庫

mysqldump -u username -p password -B dbName1 dbName1|gzip > all.sql.gz

恢復的方式安裝什么的來

 

MySQL的分庫備份的命令:

mysql -S /data/3306/mysql.sock  -uroot -p123 -e "show databases;"|grep -iv "informa|perfo|database"|sed -r 's#([a-z0-9].*$)#mysqldump -uroot -p123 -S /data/3306/mysql.sock -B \1|gzip > /tmp/\1.gz#g'|bash

 

備份的腳本:

basedir=/tmp/mysqlback

for dbname in $(mysql -S /data/3306/mysql.sock  -uroot -p123 -e "show databases;"|grep -Eiv "informa|perfo|database|mysql");

do

        echo $dbname;

        mysqldump -uroot -p123 -B -S /data/3306/mysql.sock ${dbname}|gzip > ${basedir}/${dbname}.gz

done

注:在別名里面的alias grep=”egrep --color”在腳本里面是不生效的,只限制在命令行里面使用,在腳本里面還是要寫成grep -E 或者egrep

 

 

 

 

 

2.2.5 備份單個數據表

Mysqldump -u username -p password dbNameame tbName1(tbName2) > name.sql

 

例: mysqldump -uroot -p123 -S /data/3306/mysql.sock --compact yghdb1 student

--compact:在備份數據庫時把無關的注釋都去掉,只留下SQL語句,只限於測試環境使用,應用中應加上完整的備份

 

如果只想備份表結構而不備份數據,那么使用 -d 參數

 

[root@nfs_clinet_2 ~]# mysqldump -uroot -p123 -S /data/3306/mysql.sock --compact -d  yghdb1 student

 

/*!40101 SET @saved_cs_client     = @@character_set_client */;

/*!40101 SET character_set_client = utf8 */;

CREATE TABLE `student` (

  `t_id` varchar(32) NOT NULL,

  `t_name` varchar(60) DEFAULT NULL,

  `t_age` int(11) DEFAULT NULL,

  `t_dept` varchar(23) DEFAULT NULL,

  PRIMARY KEY (`t_id`),

  UNIQUE KEY `uni_index_age` (`t_age`),

  KEY `index_dept` (`t_dept`),

  KEY `index_name_dept` (`t_name`(3),`t_dept`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;

/*!40101 SET character_set_client = @saved_cs_client */;

 

 

 如果只想備份表中的數據,,那么把-d換成-t

[root@nfs_clinet_2 ~]# mysqldump -uroot -p123 -S /data/3306/mysql.sock --compact -t  yghdb1 student   

INSERT INTO `student` VALUES ('1101','ygh',30,'stu'),('12編號','袁國浩',23,'學士');

 

 

2.2.6如果想備份MySQL里面的所有的庫和表

那么使用 -A -B 和 --events

 

mysqldump -uroot -p123 -S /data/3306/mysql.sock -A -B --event|gzip  >/tmp/mysqlback/all.gz

 

2.2.7 mysqldump的其他參數

用來切割bin-log文件。當我們做一次備份的時候,在到下一次備份之前,數據庫數據丟失如何找回。

這就需要使用最新一次的備份數據+bin-log來找回數據庫的數據。

因此,在我們備份的時候,需要知道此時的bin-log點是很重要的,不然在下次備份前,數據庫數據丟失,那就不好恢復了。

 

因此我們使用

mysqldump -uroot -p123 -S /data/3306/mysql.sock -A -B -F --event|gzip  >/tmp/mysqlback/all.gz

來備份數據庫是一個好的做發

 

還有一個比這個更好的做法,就是使用--master-data=1這個參數,

這個參數的作業是在SQL的備份腳本中,指定當前備份對應的bin-log的內容,並且在恢復時自動恢復。是一個很好的備份數據的方法。

--master-data=2,也是可以的,這樣在SQL腳本中的bin-log將會被注釋掉,顯得的很靈活,運維可以根據自己的需要來確定是否要執行bin-log 腳本

 

[root@nfs_clinet_2 ~]#  mysqldump -uroot -p123 -S /data/3306/mysql.sock --master-data=1 --compact -B yghdb1

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000019', MASTER_LOG_POS=107; #指定bin-log的位置

 

 

-x --lock-all-tables:鎖表

 

-l lock-tables(lock all tables for read):只讀鎖表

 

--single-transaction:適合innodb引擎的事務備份,在innodb引擎中,通常使用innodb引擎來來保持備份的一致性,實際工作中,要求修改隔離級別為(REPEATBLE READ)(可重復讀)來保證本次備份時,不會備份其他已提交的事務

 

2.2.8 普通企業的數據備份方法:

myisam引擎

myslqdump -uroot -p123 -A -B --event -F --master-data=2 -x|gzip > backup.sql

 

Innodb引擎

myslqdump -uroot -p123 -A -B --event -F --master-data=2 --single-transaction|gzip > backup.sql

 

2.2.9MySQL企業的專業DBA的備份方法

 

 

 

 

2.2.10 如何把一個目錄下面的xxx.gz腳本恢復的數據庫

例如,在/tmp/mysqlback有如下的備份文件,如何把他們還原到數據庫

[root@nfs_clinet_2 mysqlback]# ll

總用量 16

-rw-r--r-- 1 root root  510 3月   5 16:12 3306d.gz

-rw-r--r-- 1 root root  509 3月   5 16:12 test.gz

-rw-r--r-- 1 root root 1014 3月   5 16:12 yghdb1.gz

-rw-r--r-- 1 root root  780 3月   5 16:12 yghdb2.gz

 

A)首先解壓全部的文件使用如下的命令

gzip -d *.gz

然后執行下面的腳本

basedir=/tmp/mysqlback/

cd $basedir

for dbname in `ls * `;

do

         mysql -uroot -p123 -S /data/3306/mysql.sock < $dbname;

done

 

2.2.11 使用mysqlbinlog 來恢復數據庫

按照數據庫來拆分bin-log

mysqlbinlog -d yghdb1 mysql-bin.000020

通用寫法:

Mysqlbinlog -d dbName binlogFile

 

指定位置來恢復數據庫

mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456
| mysql -u root -pmypwd
mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456
| mysql -u root -pmypwd

 

指定時間恢復:

mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456
| mysql -u root -pmypwd

 

 

 

 

 

 

 

2.3 MySQL的亂碼問題

MySQL的亂碼問題主要是由於客戶端和服務器的字符集編碼不一致所造成的。

使用

show create database yghdb1(dbName)\G; #查看數據庫的字符集編碼

show create table teacher(tableName)\G; #查看數據庫表的字符集編碼

 

在創建數據庫的時候可以指定數據庫或者數據表的字符集,例如下面的語句:

create database yghdb1 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; #指定數據的字符編碼gbk

當然數據的默認編碼格式可以在編譯中指定,也可以在my.cnf中進行配置,可以參考下面的文檔。

 

使用”show character set;”可以查看MySQL支持的字符集編碼

 

 

如何想讓數據庫不亂碼,可以使用 set names gbk; #指定數據庫客戶端的編碼,但這只是臨時生效

 

這樣讓MySQL的客戶端和服務器字符編碼統一,就不會亂碼了。

 

在配置數據庫配置文件中指定,在

5.1及以前的版本,在

[client] #MySQL客戶端編碼

default-character-set=utf8

[mysqld] #MySQL的服務器編碼

default-character-set=utf8

 

在5.5的配置文件中,下面的兩種方式人選其一即可

 

[client] #MySQL客戶端編碼

default-character-set=utf8

character-set-server=utf8

[mysqld] #MySQL的服務器編碼

default-character-set=utf8

character-set-server=utf8

 

或者在使用source的腳本導入mysql腳本時,加上set names utf8.#指定客戶端的字符集。但是服務端的字符集還有和SQL腳本統一。

 

查看MySQL的字符編碼情況:

mysql> show variables like '%character_set%';

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

| Variable_name            | Value                                     |

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

| character_set_client     | utf8                                      |

| character_set_connection | utf8                                      |

| character_set_database   | utf8                                      |

| character_set_filesystem | binary                                    |

| character_set_results    | utf8                                      |

| character_set_server     | utf8                                      |

| character_set_system     | utf8                                      |

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

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

8 rows in set (0.00 sec)

 

保證上面的統一就不會亂碼了,而且MySQL客戶端如果不指定,默認和系統的字符集編碼一樣。

 

 

如果你的Linux不支持中文,那么你可以去修改Linux的字符集編碼

編輯vim /etc/sysconfig/i18n

LANG="zh_CN.UTF-8"

 

推薦使用utf-8的編碼

 

 

 

 

3 MySQL的優化

3.1 使用explain來查看SQL語句的執行

現在有一張表的數據和描述如

mysql> select *from teacher;

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

| t_name | age  | t_id |

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

| ygh1   |   12 | 1101 |

| ygh2   |   13 | 1102 |

| ygh3   |   14 | 1103 |

| ygh4   |   15 | 1104 |

| ygh5   |   16 | 1105 |

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

5 rows in set (0.00 sec)

 

mysql> desc teacher;

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

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

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

| t_name | varchar(23) | YES  |     | NULL    |       |

| age    | int(11)     | YES  |     | NULL    |       |

| t_id   | varchar(32) | NO   | MUL | NULL    |       |

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

3 rows in set (0.00 sec)

 

 

分別使用索引搜索和無索引搜索

mysql> explain select *from teacher where t_name='ygh5'\G;

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

           id: 1

  select_type: SIMPLE

        table: teacher

         type: ALL

possible_keys: NULL #無可用索引

          key: NULL

      key_len: NULL

          ref: NULL

         rows: 5 #搜索了五條記錄

        Extra: Using where

1 row in set (0.00 sec)

 

ERROR:

No query specified

 

mysql> explain select *from teacher where t_id='1105'\G;  

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

           id: 1

  select_type: SIMPLE

        table: teacher

         type: ref

possible_keys: index_id #可用索引

          key: index_id

      key_len: 66

          ref: const

         rows: 1 #搜索了一條記錄

        Extra: Using where

1 row in set (0.02 sec)

 

3.2 登錄時加上-U來防止用戶誤操作

正常登錄進入MySQL,如果執行這條語句是會執行成功的。

update teacher set t_name='ygh';

但是如果我們在登錄時添加一個參數

 mysql -uroot -p123 -S /data/3306/mysql.sock -U

那么在執行update teacher set t_name='ygh';就會有下面的報錯:

mysql> update teacher set t_name='ygh';

ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

 

可用使用別名來防止誤操作

 

 

3.3 打開MySQL的日志監控

在MySQL的配置文件中,我們可以加上一條配置

log-bin = /data/3306/mysql-bin

這樣所有的MySQL的修改或者插入操作都會記錄在這個文件里面,但是

這個文件是一個日志文件,使用vim無法查看,只能使用

 Mysqlbinlog 來查看

 之所以要加上日志文件,是為了數據庫被誤操作或者黑客攻擊以后可以進行恢復。

 

 

3.4 生產中,如何修改已經正在使用的數據庫字符集

例如latin1 --> utf8

A)首先停止數據庫的服務

B)建庫已經建表語句的導出,修改latin1為utf8

C)導出MySQL的所有數據

D)修改MySQL的服務端和客戶端編碼為utf8

E)刪除原來的所有表和數據

F)導入新的建庫語句

G)導游已備份的所有數據。

 

在企業應用中,應提前指定好編碼。

 

 

3.5 MySQL的一些常用的查看命令

-e 這個參數,可以在命令行直接執行MySQL的命令,方便shell編程和數據的導入導出

 

show processlist;#查看MySQL的所有的連接數

 

[root@nfs_clinet_2 mysqlback]#  mysql -uroot -p123 -S /data/3306/mysql.sock -e "show processlist";

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

| Id | User | Host      | db   | Command | Time | State | Info             |

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

| 86 | root | localhost | NULL | Query   |    0 | NULL  | show processlist |

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

 

 

 

show variables;#查看MySQL的參數,只要在配置文件中配置,基本上都能查到,也可以檢查配置文件里面配置的內容是否生效

 

 mysql -uroot -p123 -S /data/3306/mysql.sock -e "show variables";

例:

[root@nfs_clinet_2 mysqlback]#  mysql -uroot -p123 -S /data/3306/mysql.sock -e "show variables;"|grep "log_bin"

log_bin ON

log_bin_trust_function_creators OFF

sql_log_bin     ON

 

 

show global status:查看MySQL的全局狀態,我們可以把MySQL的狀態參數提取出來,然后做成一張狀態圖,對MySQL的性能進行時時的監測

mysql -uroot -p123 -S /data/3306/mysql.sock -e "show global status;"

例:

[root@nfs_clinet_2 mysqlback]#  mysql -uroot -p123 -S /data/3306/mysql.sock -e "show global status;"|grep select

Com_insert_select       0

Com_replace_select      0

Com_select      456

#查看一共進行了多少此的select

 

 

show variables #查看MySQL的參數

 mysql -uroot -p123 -S /data/3306/mysql.sock -e "show variables;"

 

 

關於修改啟動中MySQL的參數問題:

我們知道,MySQL的參數寫在配置文件中,如果我們修改配置文件,那需要重啟MySQL才能生效,那么如果在不重啟MySQL的情況下,修改MySQL一些參數的大小

 

例如在/data/3306/my.cnf中key_buffer_size = 16M,但是我現在需要調整他為32M,而且MySQL正在運行,如何調整:

方法:

首先查看全局參數有沒有這個參數

 mysql -uroot -p123 -S /data/3306/mysql.sock -e "show variables;"|grep "key_buffer_size"

key_buffer_size 16777216

#發現有,我們可以登錄MySQL進行修改

 

mysql> show variables like "%key_buffer%";

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

| Variable_name   | Value    |

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

| key_buffer_size | 16777216 |

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

1 row in set (0.00 sec)

其實在MySQL中也可以進行查詢

 

 

 

mysql> set global key_buffer_size=1024*1024*32; #設置新的值

Query OK, 0 rows affected (0.02 sec)

 

mysql> show variables like "%key_buffer%";     

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

| Variable_name   | Value    |

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

| key_buffer_size | 33554432 |

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

1 row in set (0.00 sec)

 

#結果竟然被改變了,但是如果重新啟動MySQL,就會失效,因為MySQL就會配置文件里面讀取。

 

所有修改正在啟動的MySQL的參數的方法:首先登錄MySQL進行修改,然后在配置文件修改,類似修改SELinux和hostname

 

 

 

4 MySQL的主從復制

 

原理圖:

 

 

 

 

 

 

 

 

主從復制的操作步驟:

 

A):准備工作,先准備兩個虛擬主機或者兩個多實例的MySQL,一個作為主庫,一個作為從庫。我這里使用MySQL的多實例,以3306作為MySQL的主庫,以3307作為從庫

 

B)先打開主庫的bin-log的日志功能log-bin = /data/3306/mysql-bin

 

C)分別查看兩個實例的my.cnf,確保兩個多實例的server-id的不同

 

[root@nfs_clinet_2 3306]# grep server-id /data/3306/my.cnf  /data/3307/my.cnf

 

/data/3306/my.cnf:server-id = 1

 

/data/3307/my.cnf:server-id = 3

 

 

 

D)在主庫創建從庫的訪問用戶,並給予權限

 

grant replication slave on *.* to 'rep'@'192.168.204.%' identified by '123';

 

 

 

E)給主庫備份數據

 

 mysqldump -uroot -p123 -S /data/3306/mysql.sock -A -B --events --master-data=1 -x > /tmp/mysqlback/all.sql

 

 

 

less /tmp/mysqlback/all.sql 查找CHANGE ,你會發現MASTER_LOG_POS=756;

 

和在3306數據庫使用show master status的值是一樣的。

 

mysql> show master status;

 

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

 

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

 

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

 

| mysql-bin.000020 |      756 |              |                  |

 

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

 

 

 

F)把主庫備份好的數據導入到從庫

 

 mysql -uroot -p123 -S /data/3307/mysql.sock < /tmp/mysqlback/all.sql

 

 

 

G)登錄從庫的3307,執行change master操作

 

mysql> change master to

 

    -> master_host='192.168.204.130',#主服務器IP

 

    -> master_user='rep',   #上面主庫配置的用戶

 

    -> master_password='123',#用戶的密碼

 

    -> master_log_file='mysql-bin.000020', #備份主庫時bin-log文件

 

    -> master_log_pos=756; #位置,從上面的show master status得出

 

Query OK, 0 rows affected (0.33 sec)

 

 

 

H)登錄3307MySQL實例,開啟slave主從復制

 

start slave;

 

然后執行 show slave status\G;如果看到下面的信息IOSQL這兩個線程已經啟動了。

 

 

 

  Slave_IO_Running: Yes

 

            Slave_SQL_Running: Yes

 

 

 

I)檢查和測試,在主庫創建一個數據庫,在從庫使用show database看主庫和從庫是否一致

 

 

 

 

 

如果從庫還想級聯從庫,需要打開從庫的bin-loglog-server-update

 

 

 

 

 

 

 

企業快速的MySQL主從復制方案:

 

 

 

 

 

 

 

 

 

 

MySQL的錯誤代碼對於的問題:

 

 

 

My.cnf中和MySQL主從同步的參數介紹

 

 

 

 

 

如何保證從庫的只讀:在從庫的配置文件的[mysqld]模塊下面加上read-only

 

但是read-only只對普通用戶生效,對超級用戶(root)不生效。建議使用web使用普通用戶來訪問數據庫。

 

 

 

5 企業MySQL服務宕機的解決思路

 

5.1 MySQL服務器主庫宕機

 

對於服務器宕機的問題,首頁要做好計划,不要臨時准備,不然會出現很多問題

 

進入從庫,使用show slave status\G;

 

如果看見Slave_IO_State: Waiting for master to send event

 

表明從庫是最新的,否則需要手動的獲取主庫的bin-log文件,手動對最新的一個從庫進行數據恢復

 

 

 

然后進行一個已經是最新數據的主庫,然后執行如下的命令:

 

stop slave; reset master;quit;

 

再進行從庫的/data目錄,刪除master.info,relay-log.info

 

編輯從庫的my.cnf,注釋掉read-onlylog-slave-updates等配置,打開bin-log

 

創建從庫的用戶

 

 

 

其他的從庫需要stop slave;change master to new master;start slave;

 

最后修復宕機的主庫,作為從庫使用或者重新掛載到主庫

 

 

MySQL5.5支持一個半同步插件,保證一個從庫和主庫的數據是一致的,可以試試

 

 

 

5.2 從庫的服務器宕機

 

在企業中,從庫盡可能的多於兩個,防止因一個從庫宕機,導致服務不能進行正常的功能。

 

從庫宕機很簡單,刪除所有的數據,從新做一個從庫即可。

 

 

 

 

6 MySQL的存儲引擎介紹

 

參考了別人的博客,下面是具體的連接

 

http://www.cnblogs.com/kevingrace/p/5685355.html

 

附上我自己的博客:MySQL的配置文件的翻譯,可以參考翻譯來通過配置文件的參數對MySQL性能進行調整優化

 

http://www.cnblogs.com/yghjava/p/6372460.html

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM