01-06-2018, 02:10 PM
Dur de résumer toutes ses connaissances des 10 dernières années en 5 lignes, mais:
- Encapsule toutes les manipulations de chaque page et de chaque CRON dans une transation (dont le principe est d'assurer que personne ne viendra modifier les données pendant que tu les traites). $pdo->beginTransaction pour la démarrer / $pdo->commit pour la terminer et valider les données / $pdo->rollback pour la terminer mais annuler les modifications [de mémoire, aka les noms des méthodes sont peut-être un poil différents). START TRANSACTION / COMMIT / ROLLBACK si tu es en SQL pur (ie dans des procédures stockées)
- Passe toutes tes tables MyISAM en InnoDB. D'une part, tu auras la possibilité de faire des FOREIGN KEY (je te laisse chercher les tutos du net pour savoir ce que c'est puis voir la doc MySQL pour vraiment comprendre et bien les utiliser) mais tu auras également les lock par ligne et non par table (actuellement, si tu fais un UPDATE sur 1 ligne de ta table MyISAM, alors toute la table sera lockée jusqu'à ce que la transaction soit terminée, ce qui est ingérable)
- Dans le cas de tes SELECT, je pense que tu n'as pas besoin d'un FOR UPDATE/LOCK IN SHARE MODE. Donc on va s'en passer (mais jette un oeil sur la doc pour comprendre ce que cela fait; sur le principe, cela lock la ligne de sorte que les autres transactions ne puissent ni la lire ni l'écrire dans le 1er cas, et juste pas l'écrire mais pouvoir la lire dans le 2nd, de mémoire)
- Dans l'idéal, il faudrait voir le traitement que tu fais, car il y a 99% de chances que ce soit mal goupillé et ultra-fat pour rien. Partage le code en question si tu veux de l'aide là dessus. Cela allègera le temps de calcul.
- Ce n'est pas normal que tu ne scale pas bien avec la "grosseur" du joueur. Je pense que l'algo que tu as est très mauvais (sans être vexant). Partage le code pour qu'on puisse aider (via GitHub ou Mercurial-assimilé au mieux, ou dans un post au pire)
- Non, je veux dire que MyISAM verrouille toute la table quand il modifie 1 seule ligne, et personne (= aucune autre transaction) ne peut y accéder. Ce qui va donc bloquer les autres pages du jeu (= les autres joueurs)
- Non, dans la même transaction, UPDATE & SELECT sur une même ligne peuvent se faire. C'est même souvent indispensable. En revanche, l'UPDATE va "bloquer" la ligne de sorte que d'autres pages ne puissent pas y accéder tant que la transaction n'est pas terminée. Sinon, imagine, tu fais un SELECT dans ton CRON, tu récupère des data, une autre page s'exécute à ce moment-là et met la ligne à jour, puis ton CRON mets à jour cette ligne: ton CRON aurait alors écrasé les modifications de la page (cela s'appelle des accès concurrents). Les transactions sont là pour ça, et MyISAM ne les gère pas convenablement (voire pas du tout peut-être...)
- Encapsule toutes les manipulations de chaque page et de chaque CRON dans une transation (dont le principe est d'assurer que personne ne viendra modifier les données pendant que tu les traites). $pdo->beginTransaction pour la démarrer / $pdo->commit pour la terminer et valider les données / $pdo->rollback pour la terminer mais annuler les modifications [de mémoire, aka les noms des méthodes sont peut-être un poil différents). START TRANSACTION / COMMIT / ROLLBACK si tu es en SQL pur (ie dans des procédures stockées)
- Passe toutes tes tables MyISAM en InnoDB. D'une part, tu auras la possibilité de faire des FOREIGN KEY (je te laisse chercher les tutos du net pour savoir ce que c'est puis voir la doc MySQL pour vraiment comprendre et bien les utiliser) mais tu auras également les lock par ligne et non par table (actuellement, si tu fais un UPDATE sur 1 ligne de ta table MyISAM, alors toute la table sera lockée jusqu'à ce que la transaction soit terminée, ce qui est ingérable)
- Dans le cas de tes SELECT, je pense que tu n'as pas besoin d'un FOR UPDATE/LOCK IN SHARE MODE. Donc on va s'en passer (mais jette un oeil sur la doc pour comprendre ce que cela fait; sur le principe, cela lock la ligne de sorte que les autres transactions ne puissent ni la lire ni l'écrire dans le 1er cas, et juste pas l'écrire mais pouvoir la lire dans le 2nd, de mémoire)
- Dans l'idéal, il faudrait voir le traitement que tu fais, car il y a 99% de chances que ce soit mal goupillé et ultra-fat pour rien. Partage le code en question si tu veux de l'aide là dessus. Cela allègera le temps de calcul.
- Ce n'est pas normal que tu ne scale pas bien avec la "grosseur" du joueur. Je pense que l'algo que tu as est très mauvais (sans être vexant). Partage le code pour qu'on puisse aider (via GitHub ou Mercurial-assimilé au mieux, ou dans un post au pire)
- Non, je veux dire que MyISAM verrouille toute la table quand il modifie 1 seule ligne, et personne (= aucune autre transaction) ne peut y accéder. Ce qui va donc bloquer les autres pages du jeu (= les autres joueurs)
- Non, dans la même transaction, UPDATE & SELECT sur une même ligne peuvent se faire. C'est même souvent indispensable. En revanche, l'UPDATE va "bloquer" la ligne de sorte que d'autres pages ne puissent pas y accéder tant que la transaction n'est pas terminée. Sinon, imagine, tu fais un SELECT dans ton CRON, tu récupère des data, une autre page s'exécute à ce moment-là et met la ligne à jour, puis ton CRON mets à jour cette ligne: ton CRON aurait alors écrasé les modifications de la page (cela s'appelle des accès concurrents). Les transactions sont là pour ça, et MyISAM ne les gère pas convenablement (voire pas du tout peut-être...)