LoadMonitorMySQL.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. * @ingroup Database
  20. */
  21. namespace Wikimedia\Rdbms;
  22. use BagOStuff;
  23. use WANObjectCache;
  24. /**
  25. * Basic MySQL load monitor with no external dependencies
  26. * Uses memcached to cache the replication lag for a short time
  27. *
  28. * @ingroup Database
  29. */
  30. class LoadMonitorMySQL extends LoadMonitor {
  31. /** @var float What buffer pool use ratio counts as "warm" (e.g. 0.5 for 50% usage) */
  32. private $warmCacheRatio;
  33. public function __construct(
  34. ILoadBalancer $lb, BagOStuff $srvCache, WANObjectCache $wCache, array $options = []
  35. ) {
  36. parent::__construct( $lb, $srvCache, $wCache, $options );
  37. $this->warmCacheRatio = $options['warmCacheRatio'] ?? 0.0;
  38. }
  39. protected function getWeightScale( $index, IDatabase $conn = null ) {
  40. if ( !$conn ) {
  41. return parent::getWeightScale( $index, $conn );
  42. }
  43. $weight = 1.0;
  44. if ( $this->warmCacheRatio > 0 ) {
  45. $res = $conn->query( 'SHOW STATUS', __METHOD__ );
  46. $s = $res ? $conn->fetchObject( $res ) : false;
  47. if ( $s === false ) {
  48. $host = $this->lb->getServerName( $index );
  49. $this->replLogger->error( __METHOD__ . ": could not get status for $host" );
  50. } else {
  51. // https://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html
  52. if ( $s->Innodb_buffer_pool_pages_total > 0 ) {
  53. $ratio = $s->Innodb_buffer_pool_pages_data / $s->Innodb_buffer_pool_pages_total;
  54. } else {
  55. $ratio = 1.0;
  56. }
  57. // Stop caring once $ratio >= $this->warmCacheRatio
  58. $weight *= min( $ratio / $this->warmCacheRatio, 1.0 );
  59. }
  60. }
  61. return $weight;
  62. }
  63. }