天天看點

mysqldump導出CSV格式及where導出時間範圍問題解決

  衆所周知,mysqldump不但可以導出sql格式,還可以導出csv格式。

  導出CSV格式的具體使用如下指令。

mysqldump -uroot -ppassword -S /tmp/mysql9991.sock heartbeat -t -T /data1/mysql9991/      

  導出後,會生成2個檔案,一個tablename.sql為表結構,另一個tablename.txt為資料内容。

  需要注意的是:

  1、-T 參數跟的是目錄path,不是檔案名。

  2、這個path必須是導出源mysql具有可寫權限的,否則報錯如下。

mysqldump -uroot -ppassword -S /tmp/mysql9991.sock heartbeat alive -t -T /data1/
mysqldump: Got error: 1: Can't create/write to file '/data1/alive.txt' (Errcode: 13) when executing 'SELECT INTO OUTFILE'      

  3、使用的使用者需要有select和file2個權限。

  4、使用fields-terminated-by和lines-terminated-by可以自定義字段分割符和行分隔符

  5、mysqldump導出csv格式隻能在本地進行,無法遠端操作。

  但是很少有人知道mysqldump可以支援where條件導出,具體的方法如下:

mysqldump -uroot -ppassword -S /tmp/mysql9991.sock heartbeat alive -w "time between '2013-12-22 00:00:00' and '2013-12-22 23:59:59'" > 1.txt      

  或者

mysqldump -uroot -ppassword -S /tmp/mysql9991.sock heartbeat alive -w "time between '2013-12-22 00:00:00' and '2013-12-22 23:59:59'"  -t -T /data1/mysql9991/        

  最近利用利用這個特性在導出一個時間段的資料的時候突然發現遇到如下問題:

### 首先使用如下指令導出資料
mysqldump -uroot -ppasswrod -S /tmp/mysql9991.sock heartbeat alive -w "time between '2013-12-22 00:00:00' and '2013-12-22 23:59:59'" > 1.txt

### 檢視内容ok
INSERT INTO `alive` VALUES ('2013-12-22 00:00:00','2013-12-22 00:00:00')...................省略n多内容。

### 重新導入庫中後發現,内容變了
source 1.txt
select * from alive limit 3;      

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

| time | systime |

| 2013-12-22 08:00:00 | 2013-12-22 08:00:00 |

| 2013-12-22 08:00:01 | 2013-12-22 08:00:01 |

| 2013-12-22 08:00:02 | 2013-12-22 08:00:02 |

3 rows in set (0.00 sec)

  從上面我們可以看到,sql檔案中的時間是12月22日0點0分0秒,那麼為什麼重新灌入庫中就變成了12月22日8點0分0秒了呢?

  聰明的同學應該已經反應出來了,8小時是标準的時區設定,這必然和時區有關。man一下mysqldump之後發現果然和時區有關,有個關鍵參數是--tz-utc這個參數解釋如下:

--tz-utc

          This option enables TIMESTAMP columns to be dumped and reloaded between servers in different time zones.
          mysqldump sets its connection time zone to UTC and adds SET TIME_ZONE=’+00:00’ to the dump file. Without this
          option, TIMESTAMP columns are dumped and reloaded in the time zones local to the source and destination
          servers, which can cause the values to change.  --tz-utc also protects against changes due to daylight saving
          time.  --tz-utc is enabled by default. To disable it, use --skip-tz-utc. This option was added in MySQL
          5.0.15.      

  從解釋中看到,預設--tz-utc是打開的,而這個參數會影響timestamp的。他會預設設定時區為time_zone=‘+00:00’,而由于我們所在的時區是‘+08:00’是以自然會增加8個小時。(所在時區可以使用date +%z查詢)

  如解釋中可以使用--skip-tz-utc來解決這個問題,我們重新dump一次,對比兩次的檔案可以更明顯的看出來,沒有添加參數的多出了time zone的配置。

### 第一次沒有加參數的配置
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

### 第二次添加 --skip-tz-utc
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;      

  至此,問題解決。

  突然發現,即使是我們經常使用的指令,依然有很多不知道的參數,看來還需要多多研究,另外就是,善用man,其實問題的解決方法都已經放在了哪裡。

繼續閱讀