2

Je ne trouve pas d'informations en ligne à ce sujet.Modification d'une table partitionnée

Quelle est la meilleure façon de modifier une table déjà partitionnée?

dois-je simplement utiliser la

normale
UPDATE `table` MODIFY COLUMN `column_name` TINYINT(1) DEFAULT 1 NOT NULL; 

et verrouiller la table pendant plusieurs minutes

ou devrais-je utiliser cette partition de commande par partition?

UPDATE `table` PARTITION (p0) MODIFY COLUMN `column_name` TINYINT(1) DEFAULT 1 NOT NULL; 

Quelles sont vos recommandations? Que se passe-t-il si toutes les partitions ne sont pas exactement égales? est-ce que c'est possible?

Ceci est la create:

CREATE TABLE `redirects` (
    `emailhash` varchar(100) NOT NULL, 
    `f_email_log` varchar(50) NOT NULL, 
    `linknum` int(11) NOT NULL DEFAULT '1', 
    `redirect` varchar(500) NOT NULL, 
    `clicked` int(11) NOT NULL DEFAULT '0', 
    `clicktime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
    PRIMARY KEY (`emailhash`), 
    KEY `f_email_log` (`f_email_log`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
/*!50100 PARTITION BY KEY (emailhash) 
PARTITIONS 16 */ 

Le tableau a environ 40 millions de disques. Je veux réduire la taille de certains champs comme INT à TINYINT puisque ces valeurs sont principalement 1-30 ou 0/1, ainsi que les longueurs de varchar depuis que j'ai trouvé que ces nombres sont trop grands et peuvent être réduit.

Répondre

1

La modification d'une table partitionnée nécessite de modifier chaque partition une à la fois. Pendant ce temps, la table entière doit être verrouillée, sinon, les lectures/écritures trébucheront sur un Alter à moitié fini.

Veuillez indiquer SHOW CREATE TABLE, le nombre de partitions, la justification du partitionnement et indiquer quelle colonne doit être modifiée. Nous pourrions être en mesure de proposer une solution de rechange.

Plus

lignes de 400M seraient environ 12 Go pour ce schéma?
4 Go buffer_pool (qui pourrait être porté à 11G pour beaucoup RAM)
md5 pour la clé
-> 67% des inserts et sélectionne ne trouvera pas le bloc souhaité dans la RAM (cache), donc devrait frapper la disque. Cela conduit à des performances lentes. Cela ne fera qu'empirer à mesure que la table se développe. Et peu importe qu'il soit partitionné ou non. (Non, je ne peux pas expliquer la différence que vous signalez.)

Voir here pour plus de discussion, mais pas de bonne solution pour votre cas d'utilisation.

Réduire les types de données (4 octets INT -> 1 octet TINYINT UNSIGNED, etc) aidera certains. UNHEX(md5) vous permet de mettre le hachage en 16 octets: BINARY(16), économisant ainsi quelque chose comme 18 octets sur ce que vous avez maintenant. Réduire le maximum sur VARCHAR a peu ou pas d'effet. Idem pour CHARACTER SET.

La requête aurait besoin where emailhash=UNHEX('abcdef1234567890')

ALTER

Retour à la question initiale de savoir comment faire la ALTER "rapide". À moins que vous ayez déjà configuré la réplication, vous n'avez généralement pas de chance.Les partitions doivent toujours avoir le même schéma, donc votre idée de les modifier une à une n'est pas possible.

Mais ... vérifiez pt-online-schema-change et gh-ost pour voir s'ils fonctionneront avec des tables partitionnées.

+0

J'ai ajouté le code à la question d'origine. Une idée? –

+0

'PARTITION BY KEY (la clé primaire)' est inutile pour la performance. Qu'espérez-vous gagner en partitionnant? En outre, il y a environ 100 Mo de surcharge pour une table à 16 partitions. –

+0

En supposant que "hash" est très aléatoire, vous êtes obligé de sauter autour de la table tout le temps. Je suppose que vous n'avez pas assez de RAM pour mettre en cache toute la table? D'où la performance va souffrir. –