Metabase 從 H2 遷移到 MySQL 踩坑指南


寫在前面的話

 

首先如果你看到了這篇文章,可能你就已經指定 Metabase 是啥了,我這里還是簡單的做個說明:

Metabase is the easy, open source way for everyone in your company to ask questions and learn from data。

官網是這樣描述的,這是一款 BI 開源工具,能讓你的數據以漂亮的圖表顯示出來,雖然我覺得並不是很好看,但是還是叫漂亮吧。同類的產品還有 Superset,Redash 等等。

感興趣的可以看看官網:

https://www.metabase.com/

也可以研究下 GITHUB:

https://github.com/metabase/metabase

 

 

數據遷移

 

故事是醬嬸兒滴,公司准備搞一個這樣的系統,然后交給就讓我搭建了這幾個出來做橫向比較。當然,我就是把他運行起來,至於配置都丟給了數據組的老哥。然后這個環境就慢慢的配置越來越多。最后一拍腦門就選它了。於是不可能重新配置啊,這樣就得把項目遷移到雲上。

問題出現了,因為之前我是以 demo 形式搭建丟給他們的,所有數據庫這些啥都是默認是,Metabase 的默認是 H2 數據庫。在搞這個之前我根本不知道這是啥。然后網上找了很多導出數據的方式都特么扯皮。各種報錯或者根本不能用。

問題出在哪里呢?就處在將數據導出到 MySQL 的時候,報錯:Data too long xxxx

既然說到這里,那就先回顧一下我的遷移過程:

【1】首先我們先停止在運行 metabase 服務,我是直接 jar 形式運行的,kill 掉就行。

【2】此時我們可以看到默認運行的時候,在 jar 的目錄下存在兩個數據庫的文件:

上面兩個 db 文件就是用到 H2 數據庫了,我們把這 3 個文件移動到其他目錄備份,相當重要,不然掛了你就哭吧!!!

 

【3】此時我們新建一個 metabase 的庫(我的是 MySQL 5.7):

CREATE DATABASE metabase default charset utf8 COLLATE utf8_general_ci;
grant all on metabase.* to 'metabase'@'%' identified by '123456';

 

【4】配置好連接數據庫的環境變量,由於我們是 jar 啟動的,這個服務會默認去先讀取環境變量(在 /etc/profile 里面追加):

export MB_DB_TYPE=mysql
export MB_DB_DBNAME=metabase
export MB_DB_PORT=3306
export MB_DB_USER=metabase
export MB_DB_PASS=123456
export MB_DB_HOST=192.168.10.204
export MB_JETTY_PORT=8000
export MB_JETTY_HOST=0.0.0.0

我這里指定了數據庫連接,已經服務啟動以后監聽的 IP 和端口,當然,數據庫那一部分可以簡寫:

export MB_DB_CONNECTION_URI="mysql://192.168.10.204:3306/metabase?user=metabase&password=123456&useSSL=false"

寫成 jdbc 的樣式,這樣我們可以指定 SSL 為 false,否則日志有點惡心。

記得讓新增的環境變量生效:

source /etc/profile

 

【5】生效之后,我們就按照網上的方法開始同步,這也是問題開始的地方:

/opt/jdk1.8.0_45/bin/java -jar metabase.jar load-from-h2 ./metabase.db

我們 jdk 是沒有配置環境變量的,所有用的是絕對路徑,你們可以根據自己修改。一切就這樣往美滋滋的方向發展,MySQL 里面也已經開始創建新的表了。

正當一切過的美滋滋,准備搞完就休息的時候,不幸的事情發生了:

為了方便需要的兄弟更容易檢索這篇文章,我這里把錯誤貼出來:

Transfering 2224 instances of FieldValues...........[OK]
Transfering 721 instances of Revision......BatchUpdateException:
 Message: Data truncation: Data too long for column 'object' at row 1
 SQLState: 22001
 Error Code: 1406
java.sql.BatchUpdateException: Data truncation: Data too long for column 'object' at row 1

提示數據過長,字段長度不夠,導致數據傳輸報異常,傳輸終止。於是我在這個問題上面卡了至少兩個小時,各種搜索文檔,找 issue,都沒有解決。可能是我英語太爛。

最后還是回歸到報錯本身,既然長度不夠,那我加長度唄,但是我下次同步會不會又把我的表干掉重新建立呢?最終抱着試一試的態度,我去修改表的字段。

問題又來了,那這報錯的表是哪一個呢?我們只知道字段啊。給大家推薦一個方法,遇到這種問題,我們完全可以把表結構導出來,然后去搜索指定的列。

最終,在 revision 表中找到了這個字段,此時再看報錯:Transfering 721 instances of Revision......BatchUpdateException:,這讓我們更加確定就是這個字段。

一看他的類型 text,於是我們將它改成 longtext。

再次執行之前的命令同步,后面還會有幾個字段出現類似的報錯,類似 report_card 這些表,只需要再度修改為 longtext 類型即可。這里就不再贅述。

 

【6】同步完成以后只需要啟動服務即可使用以 MySQL 作為數據庫的 Metabase 了。

 

這里附帶一個我的 jar 服務啟動腳本,可以方便我們管理這種單個服務:

#!/bin/bash

#################################################################
# 作者:Dylan <1214966109@qq.com>
# 時間:2018-03-29
# 用途:Metabase 啟動管理
#################################################################
if [ -f /etc/init.d/functions ]; then 
    . /etc/init.d/functions
fi


#################################################################
# 定義變量
#################################################################
SERVICE_NAME='metabase'
SERVICE_PACKAGE="${SERVICE_NAME}.jar"
SERVICE_PATH='/opt/METABASE'
LOG_PATH="${SERVICE_PATH}/logs"
JAVA_CMD='/opt/jdk1.8.0_45/bin/java'


#################################################################
# 判斷日志目錄
#################################################################
if [[ ! -d ${LOG_PATH} ]]; then
    mkdir -p ${LOG_PATH}
fi


#################################################################
# 定義命令
#################################################################
function START_COMMAND()
{
    ${JAVA_CMD} -Duser.timezone=Asia/Shanghai -Xms4g -Xmx4g -jar ${SERVICE_PATH}/${SERVICE_PACKAGE} >> ${LOG_PATH}/${SERVICE_NAME}.log &
    if [[ $? -eq 0 ]]; then
        action "${SERVICE_NAME} start successed" /bin/true
    else
        action "${SERVICE_NAME} start failed" /bin/false
    fi
}

function STOP_COMMAND()
{
    SERVICE_PID=`ps -ef | grep "${SERVICE_PACKAGE}" | grep -v 'grep' | awk '{print $2}'`
    if [[ ${SERVICE_PID} == '' ]]; then
        action "${SERVICE_NAME} is not running" /bin/false
    else
        kill -9 ${SERVICE_PID} >/dev/null 2>&1
        if [[ $? -eq 0 ]]; then
            action "${SERVICE_NAME} stop successed" /bin/true
        else
            action "${SERVICE_NAME} stop failed" /bin/false
        fi
    fi
}

function STATUS_COMMAND()
{
    SERVICE_PID=`ps -ef | grep "${SERVICE_PACKAGE}" | grep -v 'grep' | awk '{print $2}'`
    if [[ ${SERVICE_PID} == '' ]]; then
        action "${SERVICE_NAME} is not running" /bin/false
    else
        action "${SERVICE_NAME} is running" /bin/true
    fi
}


#################################################################
# 定義命令
#################################################################
case "$1" in
    start)
        START_COMMAND
        ;;
    stop)
        STOP_COMMAND
        ;;
    restart|reload)
        STOP_COMMAND
        START_COMMAND
        ;;
    status)
        STATUS_COMMAND
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status|reload}"
        ;;
esac

 

 

小結

 

H2 遷移到 MySQL 出現問題可能大多都是字段的類型導致遷移失敗,另外我們在遷移的時候也可能會出現:

java.lang.IllegalArgumentException: No matching clause: :h2

這樣的報錯,這說明是環境變量的問題。

如果還有其它遷移問題,也可以留言或者加我 QQ 大家討論一下,如果你覺得這個還 OK,推薦 走一波~

另外,如果你喜歡我這博客園主題,在我博客首頁置頂文章有相關說明~

https://www.cnblogs.com/Dy1an/p/10490430.html


免責聲明!

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



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