Na netu je řada sql splitterů, které tohle zvládnou. Sami jsme před lety používali, jelo to po řádcích, takže streamové zpracování. Ručně bych to nedělal, i když s pomocí pluginu
https://github.com/vim-scripts/LargeFile jsem editoval v pohodě i 100gb dump (nedělá to nic jiného, než vypne featury vimu, které se na velkém souboru zaseknout).
Příště je lepší dumpovat jednotlivé tabulky a db, snáze se s tím pak pracuje, navíc nalití může běžet paralelně (i jednotlivé tabulky jedné DB, když se pro lití vypne kontrola referenční integrity a jedinečnosti). Ukázka dumpu (jsou v tom nějaké funkce, ale ty nejsou podstatné):
#vyrobime tab zalohu
DBS=$(mysql $LOGIN_PATH -e 'show databases;' | tail -n +2) || clean_quit "Failed reading databases" 1
# vyrobime seznamy tabulek
for DB in $DBS; do
TABLES=$(mysql $LOGIN_PATH -e "use $DB; show tables;" | tail -n +2 ) || clean_quit "Failed reading tables" 1
# dumpneme jednotlive tabulky
DB_DIR=$TMP_DATA_DIR/$DB
[ -a $DB_DIR ] && rm -rf "$DB_DIR"
mkdir -p $DB_DIR
chmod 777 $DB_DIR
echo "$TABLES" | xargs -n 1 -P 4 ionice -c 2 -n 7 mysqldump $LOGIN_PATH --max_allowed_packet=64M --default-character-set=utf8 --skip-opt --add-drop-table --add-locks --create-options --disable-keys --extended-insert --quick --set-charset --tab $DB_DIR $DB || clean_quit "Failed dumping data" 1
done
Obnovuje se něčím takovým (tohle konkrétně nejede paralelně):
#! /bin/bash -x
DB_PATH=$1
function info() {
MSG="$1"
echo "$MSG" >&2
}
function disableChecks() {
info "Disabling checks"
echo "SET @@session.unique_checks = 0;"
echo "SET @@session.foreign_key_checks = 0;"
}
function enableChecks() {
info "Enabling checks"
echo "SET @@session.unique_checks = 1;"
echo "SET @@session.foreign_key_checks = 1;"
}
function getCharset() {
TXT_FILE=$1
SQL_FILE=${TXT_FILE%.txt}.sql
grep "DEFAULT CHARSET=" $SQL_FILE | sed 's/^.*DEFAULT CHARSET=\([^ ;]*\).*/\1/g'
}
function loadInfile() {
TABLE=$1
FILE=$2
# CHARSET=$(getCharset $FILE)
CHARSET="binary"
info "Loading file $FILE into table $TABLE with charset $CHARSET"
echo "LOAD DATA INFILE '$FILE' INTO TABLE $TABLE CHARACTER SET $CHARSET;"
};
function createTables() {
DB_PATH=$1
for SQL_PATH in $(find $DB_PATH -type f -name "*.sql"); do
TABLE_FILE=$(basename $SQL_PATH)
info "Creating table ${TABLE_FILE%.sql}"
cat $SQL_PATH
done
}
function loadData() {
DB_PATH=$1
for FILE_PATH in $(find $DB_PATH -type f -name "*.txt"); do
FILE=$(basename $FILE_PATH)
TABLE="${FILE%.txt}"
loadInfile $TABLE $FILE_PATH
done
}
function recreateDB() {
DB_PATH=$1
# odstranime pripadne zaverecne lomitko, abychom na nazev adresare mohli pouzit basename
DB=$(basename ${DB_PATH%/})
info "Recreating database $DB"
echo "DROP DATABASE IF EXISTS $DB;"
echo "CREATE DATABASE $DB;"
echo "USE $DB;"
}
(
disableChecks
recreateDB $DB_PATH
createTables $DB_PATH
# vytvorime strukturu
loadData $DB_PATH
enableChecks
)