夕口技術錄

專業上的小常識,備而用之~

Category Archives: MySQL

[MySQL][SUBSTRING_INDEX]

SUBSTRING_INDEX(str,delim,count)
傳回字串 str 中在第 count 個出現的分隔符 delim 之前的幾串。如果 count 是一個正數,傳回從最後的(從左邊開始計數)分隔符到左邊所有字元。如果 count 是負數,傳回從最後的(從右邊開始計數)分隔符到右邊所有字元:

mysql> SELECT SUBSTRING_INDEX(‘www.mysql.com’, ‘.’, 2);
-> ‘http://www.mysql
mysql> SELECT SUBSTRING_INDEX(‘www.mysql.com’, ‘.’, -2);
-> ‘mysql.com

[MySQL] – ERROR 2013 (HY000): Lost connection to MySQL server during query

問題訊息:ERROR 2013 (HY000): Lost connection to MySQL server during query

情況發生:硬碟滿了,清出空間即可

[MySQL] – Got error 134 from storage engine

問題點:
storage engine 錯誤,一般就是 資料表 出錯
雖部份資料尚可進行瀏覽,
但有些是不行的。
直接進行修復即可。

如去查詢 err.log 會看到類似
091201 13:36:09 [ERROR] Got error 134 when reading table ‘./db/matrix

SQL 語法 :
REPAIR TABLE `matrix`

Table Op Msg_type Msg_text
db.matrix repair warning Number of rows changed from 2457661 to 1607686
db.matrix repair status OK

[MySQL] – 更改密碼後,無法登入phpmyadmin

問題:

# ./mysql -V
./mysql  Ver 14.7 Distrib 4.1.22, for unknown-linux-gnu (x86_64) using readline 4.3

更改密碼後,無法登入phpmyadmin
但 commend 確可以?

解答:
問題在 編碼要使用舊式的

# rm -rf /usr/local/mysql/data/mysql/
#/usr/local/mysql/bin/mysqldump -uroot -p showdown
# /usr/local/mysql/scripts/mysql_install_db –user=mysql
# /usr/local/mysql/bin/mysqld_safe –user=mysql >/dev/null &
# /usr/local/mysql/bin/mysqladmin -uroot password new-password
#/usr/local/mysql/bin/mysql -uroot -p
> SET PASSWORD FOR  ‘root’@’localhost’ = OLD_PASSWORD(‘新密碼‘);

[MySQL] – error: Got error 127 from storage engine

目前的經驗,

往往是相關資料庫表格損毀導致

因此請先進行相關表格修復動作

[MySQL] – INSERT … ON DUPLICATE KEY UPDATE

MySQL 自4.1版,
支援 INSERT … ON DUPLICATE KEY UPDATE 語法,
一方面因同事發現,

使用 REPLACE , LOCK Table,
太大量的使用 REPLACE 會造成其他的 Query 被鎖住而變慢
問題,
因此建議相關 Replace 動作改為
INSERT … ON DUPLICATE KEY UPDATE

舉例:

INSERT INTO arptable VALUES('192.168.0.1', 'ooxxooxx') ON DUPLICATE KEY UPDATE mac='mac_value';

注意,使用此語句,
必須有一個唯一索引或主鍵

 ON DUPLICATE KEY UPDATE 動作其實只會針對 mac='mac_value' 欄位進行更新,
其它欄位則不會進行更動,
因此如有二個欄位遇 ON DUPLICATE KEY UPDATE 都要更新時,
則 … ON DUPLICATE KEY UPDATE mac='mac_value' , mac2='mac2_value';

延申閱讀 mysql insert的几点操作(DELAYED 、IGNORE、ON DUPLICATE KEY UPDATE )

[MySQL] – 忘記 MySQL 密碼的處理方法

Mysql 的 root 帳號如忘記了,
要怎麼辦呢?
以下提供一個方法,
但這個方法前提之下必需將所有創建的帳號刪除…

1、找尋 mysql_install_db 的位置
[root@CentOS mysql]# locate mysql_install_db
/usr/bin/mysql_install_db

2、砍掉原有的帳號表格
[root@CentOS mysql]# rm -rf /var/lib/mysql/mysql

3、重新創建一個新的 mysql 表格
[root@CentOS mysql]# ./mysql_install_db –user=mysql

4、重啟 mysql
[root@CentOS mysql]# /etc/rc.d/init.d/mysqld start

5、重新設定 root 密碼
[root@CentOS mysql]# /usr/bin/mysqladmin -u root password ‘rootpassword’

6、登入 mysql commend 修改 root 密碼
[root@CentOS mysql]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4 to server version: 4.1.12
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.

mysql> set password for root@"localhost"=old_password(‘rootpassword’);
Query OK, 0 rows affected (0.00 sec)

7、大功完成,離開
mysql> exit
Bye

[MySQL][Collation] – 字元效對問題

以下使用一張test的表,
字符集採用的latin1。

select to_id from test where to_id=’cn象_王’;
+—————+
| to_id |
+—————+
| cn陶_陶 |
| cn象_王 |
+—————+
2 rows in set (0.00 sec)

取cn象_王的數據,居然把cn陶_陶的數據也取回來了
這顯然是不允許的。
查看它們的編碼:

# select hex(‘cn陶_陶’);
+—————-+
| hex(‘cn陶_陶’) |
+—————-+
| 636ECCD55FCCD5 |
+—————-+
1 row in set (0.00 sec)

# select hex(‘cn象_王’);
+—————-+
| hex(‘cn象_王’) |
+—————-+
| 636ECFF35FCDF5 |
+—————-+
1 row in set (0.00 sec)

編碼的確是不一樣的,但是為什麼mysql會認為這兩條記錄是一樣的呢?

一開始我們就把問題定位於collation引起的問題。

show variables查看
| collation_connection | latin1_swedish_ci
| collation_database | latin1_swedish_ci
| collation_server | latin1_swedish_ci
手工把這些參數修改為latin1_bin,結果居然一樣。這下感覺真是奇怪了。

這裡先解釋一下mysql collation的命名規則:
它們以其相關的字符集名開始,通常包括一個語言名,
並且以_ci(大小寫不敏感)_cs(大小寫敏感)_bin(二元)

比如latin1字符集有以下幾種校正規則:

校對規則 含義
latin1_german1_ci 德國DIN-1
latin1_swedish_ci 瑞典/芬蘭
latin1_danish_ci 丹麥/挪威
latin1_german2_ci 德國 DIN-2
latin1_bin 符合latin1編碼的二進制
latin1_general_ci 多種語言(西歐)
latin1_general_cs 多種語言(西歐ISO),大小寫敏感
latin1_spanish_ci 現代西班牙
最後我們將表格重建,
手工指定表格級別的collation為latin1_bin
這個問題就得到了解決。
那麼問題又來了,為什麼我前面手工測試latin1_bin時不生效呢?

原來MySQL按照下面的方式選擇表字符集和 校對規則:
如果指定了CHARACTER SET X和COLLATE Y,
那麼採用CHARACTER SET X和COLLATE Y。
如果指定了CHARACTER SET X而沒有指定COLLATE Y
那麼採用CHARACTER SET X和CHARACTER SET X的默認校對規則。
否則,採用服務器字符集和服務器校對規則。

而我們在建表的時候指定了character set,所以它永遠是採用對應的默認的校對規則。

當然我們其實也沒必要重建表格,
只需要alter table db_allot CONVERT TO CHARACTER SET latin1 COLLATE latin1_bin這樣轉換即可。

另外建議collation都盡量採用字符集相應的bin類型的校對規則,這樣不容易出錯。

Mysql BINARY POC

[MySQL][import] – ERROR 1062 (23000) at line 43238: Duplicate entry '?' for key 2

ERROR 1062 (23000) at line 43238: Duplicate entry ‘?’ for key 2

相信不少有使用 mysql -uroot -p  xxx_db_name < back_db_name.sql

指令的人,

都遇到過 Duplicate entry 的問題而無法繼續往下匯入,

這時不是把 back_db_name.sql 打開來先打問題行刪除,

就是先暫時調整 pk 的方式,

那如何我要使用強迫匯入不去管這個訊息呢?

mysql -u root xxx_db_name –force < back_db_name.sql

[Mysql][PHP] – OLD_PASSWORD 問題

php(<=4.1.22)連mysql的library過舊,
會有OLD_PASSWORD的問題
無法直接換成新版的library
需重新compiler php並下–without-mysql
再以mysql.so 的extension方式掛上
php官方手冊
In PHP 4, the option --with-mysql is enabled by default.
To disable this default behavior, you may use the --without-mysql configure option.
Also in PHP 4, if you enable MySQL without specifying the path to the MySQL install DIR, PHP will use the bundled MySQL client libraries.
In Windows, there is no DLL, it’s simply built into PHP 4.
Users who run other applications that use MySQL (for example, auth-mysql) should not use the bundled library, but rather specify the path to MySQL’s install directory, like so: --with-mysql=/path/to/mysql. This will force PHP to use the client libraries installed by MySQL, thus avoiding any conflicts.
In PHP 5, MySQL is no longer enabled by default, nor is the MySQL library bundled with PHP.

Although this MySQL extension is compatible with MySQL 4.1.0 and greater, it doesn’t support the extra functionality that these versions provide. For that, use the MySQLi extension.