Sto lottando con l'importazione di massa di una tabella InnoDB piuttosto grande composta da circa 10 milioni di righe (o 7 GB) (che per me è il tavolo più grande con cui ho lavorato finora).
Ho fatto alcune ricerche su come migliorare la velocità di importazione di Inno e per il momento la mia configurazione è simile a questa:
/etc/mysql/my.cnf/
[...]
innodb_buffer_pool_size = 7446915072 # ~90% of memory
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_thread_concurrency=0
innodb_doublewrite = 0
innodb_log_file_size = 1G
log-bin = ""
innodb_autoinc_lock_mode = 2
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_instances=8
import is done via bash script, here is the mysql code:
SET GLOBAL sync_binlog = 1;
SET sql_log_bin = 0;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';
LOAD DATA LOCAL INFILE '$filepath' INTO TABLE monster
COMMIT;
I dati sono forniti in un CSV
file.
Attualmente collaudo le mie impostazioni con piccoli "dump di test" con 2 milioni, 3 milioni, ... righe ciascuno e li utilizzo time import_script.sh
per confrontare le prestazioni.
Lo svantaggio è che ho solo un tempo di esecuzione complessivo, quindi devo attendere il completamento dell'importazione completa per ottenere un risultato.
I miei risultati finora:
- 10.000 righe: <1 secondo
- 100000 righe: 10 secondi
- 300000 file: 40 secondi
- 2 milioni di file: 18 minuti
- 3 milioni di file: 26 minuti
- 4 milioni di righe: (cancellato dopo 2 ore)
Sembra che non ci sia una soluzione per "libri di cucina" e si deve capire da soli il mix ottimale di impostazioni.
Oltre ai suggerimenti su cosa cambiare nella mia configurazione, apprezzerei molto più informazioni su come potrei valutare meglio il processo di importazione / ottenere maggiori informazioni su ciò che sta accadendo e su dove potrebbe essere il collo di bottiglia.
Ho provato a leggere la documentazione per le impostazioni che sto cambiando, ma ancora una volta non sono a conoscenza di effetti collaterali e se potrei anche ridurre le prestazioni con un valore scelto male.
Per il momento, vorrei provare un suggerimento dalla chat da utilizzare MyISAM
durante l'importazione e successivamente cambiare il motore della tabella.
Vorrei provare questo, ma per il momento la mia DROP TABLE
query richiede anche ore per terminare. (Il che sembra un altro indicatore, la mia impostazione è inferiore all'ottimale).
Ulteriori informazioni:
la macchina che sto utilizzando ha 8 GB di RAM e un disco rigido ibrido a stato solido con 5400 giri / min.
Mentre miriamo anche a rimuovere i dati obsoleti dalla tabella in questione, ho ancora bisogno di un'importazione piuttosto veloce in
a) test automatic data cleanup feature
durante lo sviluppo
eb) nel caso in cui il nostro server si arresti in modo anomalo vorremmo usare il nostro secondo server come sostituto (che richiede dati aggiornati, l'ultima importazione ha richiesto più di 24 ore)
mysql> SHOW CREATE TABLE monster\G
*************************** 1. row ***************************
Table: monster
Create Table: CREATE TABLE `monster` (
`monster_id` int(11) NOT NULL AUTO_INCREMENT,
`ext_monster_id` int(11) NOT NULL DEFAULT '0',
`some_id` int(11) NOT NULL DEFAULT '0',
`email` varchar(250) NOT NULL,
`name` varchar(100) NOT NULL,
`address` varchar(100) NOT NULL,
`postcode` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`country` int(11) NOT NULL DEFAULT '0',
`address_hash` varchar(250) NOT NULL,
`lon` float(10,6) NOT NULL,
`lat` float(10,6) NOT NULL,
`ip_address` varchar(40) NOT NULL,
`cookie` int(11) NOT NULL DEFAULT '0',
`party_id` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '2',
`creation_date` datetime NOT NULL,
`someflag` tinyint(1) NOT NULL DEFAULT '0',
`someflag2` tinyint(4) NOT NULL,
`upload_id` int(11) NOT NULL DEFAULT '0',
`news1` tinyint(4) NOT NULL DEFAULT '0',
`news2` tinyint(4) NOT NULL,
`someother_id` int(11) NOT NULL DEFAULT '0',
`note` varchar(2500) NOT NULL,
`referer` text NOT NULL,
`subscription` int(11) DEFAULT '0',
`hash` varchar(32) DEFAULT NULL,
`thumbs1` int(11) NOT NULL DEFAULT '0',
`thumbs2` int(11) NOT NULL DEFAULT '0',
`thumbs3` int(11) NOT NULL DEFAULT '0',
`neighbours` tinyint(4) NOT NULL DEFAULT '0',
`relevance` int(11) NOT NULL,
PRIMARY KEY (`monster_id`),
KEY `party_id` (`party_id`),
KEY `creation_date` (`creation_date`),
KEY `email` (`email`(4)),
KEY `hash` (`hash`(8)),
KEY `address_hash` (`address_hash`(8)),
KEY `thumbs3` (`thumbs3`),
KEY `ext_monster_id` (`ext_monster_id`),
KEY `status` (`status`),
KEY `note` (`note`(4)),
KEY `postcode` (`postcode`),
KEY `some_id` (`some_id`),
KEY `cookie` (`cookie`),
KEY `party_id_2` (`party_id`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=13763891 DEFAULT CHARSET=utf8
SHOW CREATE TABLE yourtable\G
per mostrarci la struttura della tabella di questa tabella di 10 milioni di righe.
innodb_doublewrite = 0
), l'installazione di MySQL non è protetta dagli arresti anomali: se si verifica un'interruzione dell'alimentazione (non un arresto anomalo di MySQL), i dati potrebbero essere danneggiati in modo invisibile.