Example #1
0
 public function execute()
 {
     if (!$this->isReady('thedate', 'priority')) {
         return self::IGNO;
     }
     $date1 = date('Ymd', strtotime(Setting::get('last_date')));
     $date2 = date('Ymd', strtotime($this->option('thedate')));
     if ($date1 >= $date2) {
         return self::IGNO;
     }
     $mysql = \Myfox\Lib\Mysql::instance('default');
     $count = (int) $mysql->getOne($mysql->query(sprintf('SELECT COUNT(*) FROM %stask_queque WHERE autokid < %u AND priority <= %u ' . "AND task_flag NOT IN (%d,%d) AND task_type='import'", $mysql->option('prefix'), $this->id, $this->option('priority'), \Myfox\App\Queque::FLAG_IGNO, \Myfox\App\Queque::FLAG_DONE)));
     if ($count > 0) {
         $this->setError(sprintf('Waiting for %d import task(s)', $count));
         return self::FAIL;
     }
     if (!Router::flush()) {
         $this->setError('flush route failed');
         return self::FAIL;
     }
     Setting::set('last_date', $date2, '', '集群数据最新日期');
     // TODO:
     // CALL nodefox to reload route info info cache
     return self::SUCC;
 }
 public function test_should_setting_set_without_comma_works_fine()
 {
     Setting::init(0);
     $this->assertEquals(1, Setting::set('key2', 1, 'unittest1'));
     $this->assertEquals(1, Setting::get('key2', 'unittest1'));
     $this->assertEquals(2, Setting::set('key2', 'IF(cfgvalue + 0 > 0, 2, 3)', 'unittest1', false));
     $this->assertEquals(2, Setting::get('key2', 'unittest1'));
 }
 public function test_should_import_index_works_fine()
 {
     $controller = new \Myfox\App\Control\Import();
     \Myfox\App\Setting::set('last_date', '20121031');
     ob_start();
     $controller->execute('index', array());
     $output = ob_get_contents();
     $this->assertContains('[0] OK', $output);
     $this->assertContains('"last_date":"20121031"', $output);
     @ob_clean();
 }
 public function test_should_import_index_works_fine()
 {
     $controller = new \Myfox\App\Control\Import();
     \Myfox\App\Setting::set('myfox_last_date', '20121031');
     ob_start();
     $controller->execute('index', array());
     $output = ob_get_contents();
     $this->assertContains('[0] OK', $output);
     $this->assertContains('"last_date":"20121031"', $output);
     @ob_clean();
     $controller->execute('lastdate', array());
     $output = ob_get_contents();
     $this->assertEquals($output, json_encode(array('group_name' => '__global__', 'last_date' => '20121031')));
     @ob_clean();
 }
 public function test_should_mirror_table_router_set_and_get_works_fine()
 {
     try {
         Router::set('i am not exists');
         $this->assertTrue(false);
     } catch (\Exception $e) {
         $this->assertTrue($e instanceof \Myfox\Lib\Exception);
         $this->assertContains('Undefined table named as "i am not exists"', $e->getMessage());
     }
     $mirror = \Myfox\App\Model\Table::instance('mirror');
     foreach (array(0, 1, 2, 0) as $key => $id) {
         Setting::set('last_assign_host', 0);
         $this->assertEquals(array('' => array(array('rows' => 1300, 'hosts' => '3,4,1,2', 'table' => 'mirror_0.t_' . $mirror->get('autokid') . '_' . $id))), Router::set('mirror', array(array('count' => 1300))));
         if ($key == 0) {
             $this->assertEquals(array(), Router::get('mirror'));
         }
     }
     $this->assertEquals(1, Setting::get('last_assign_host'));
     $this->assertEquals(4, Setting::get('table_route_count', 'mirror'));
     $this->assertEquals(0, (int) Setting::get('table_real_count', 'mirror'));
     $where = Router::instance('mirror')->where(null);
     $route = self::$mysql->getRow(self::$mysql->query(sprintf("SELECT autokid,route_flag,real_table,hittime,hosts_list FROM %s WHERE table_name='mirror' AND route_flag=%d LIMIT 1", $where['table'], Router::FLAG_PRE_IMPORT)));
     $this->assertEquals(0, $route['hittime']);
     $this->assertEquals('$', $route['hosts_list']);
     $real_table = $route['real_table'];
     // XXX: 数据装完
     $this->assertEquals(1, Router::effect('mirror', null, $route['real_table'], '1,2'));
     $this->assertEquals(array('hosts_list' => '1,2,$', 'route_flag' => Router::FLAG_IMPORT_END), self::$mysql->getRow(self::$mysql->query(sprintf("SELECT hosts_list,route_flag FROM %s WHERE table_name='mirror' AND real_table='%s' AND autokid = %u", $where['table'], $route['real_table'], $route['autokid']))));
     $this->assertEquals(array(), Router::get('mirror'));
     // xxx: 模拟路由生效
     Router::flush();
     $route = Router::get('mirror', null, true);
     $this->assertEquals(1, count($route));
     $route = reset($route);
     $this->assertTrue(0 < $route['mtime']);
     $this->assertEquals('1,2', $route['hosts']);
     $this->assertEquals($real_table, $route['table']);
     Router::removeAllCache();
     $query = sprintf('SELECT hittime FROM %s WHERE %s AND route_flag=%d ORDER BY autokid DESC LIMIT 1', $where['table'], $where['where'], Router::FLAG_NORMAL_USE);
     $this->assertEquals(intval(time() / 2), intval(self::$mysql->getOne(self::$mysql->query($query)) / 2));
 }
 public function test_should_import_consist_works_fine()
 {
     $hosts = self::$mysql->getAll(self::$mysql->query(sprintf('SELECT host_id, host_name FROM %shost_list WHERE host_type = %d', self::$mysql->option('prefix'), Server::TYPE_REALITY)));
     $create = "CREATE TABLE IF NOT EXISTS test.test_a (\n            id int(10) unsigned not null auto_increment primary key,\n            num1 int(10) not null default 0,\n            char1 varchar(15) not null default ''\n        ) ENGINE=MYISAM DEFAULT CHARSET=UTF8";
     $ids = array();
     foreach ($hosts as $server) {
         $mysql = Server::instance($server['host_name'])->getlink();
         $mysql->query('DROP TABLE IF EXISTS test.test_a');
         $mysql->query($create);
         $this->assertEquals(3, $mysql->query("INSERT INTO test.test_a (id,num1,char1) VALUES (1, 2, 'bbb'),(2,3,'cccc'),(3,4,'dddd')"));
         $ids[] = (int) $server['host_id'];
     }
     $this->assertEquals(1, self::$mysql->query(sprintf("INSERT INTO %sroute_info (real_table,hosts_list,table_name,modtime,route_flag)" . " VALUES ('test.test_a', '%s', 'test',%d,%d)", self::$mysql->option('prefix'), implode(',', $ids), time(), \Myfox\App\Model\Router::FLAG_IMPORT_END)));
     \Myfox\App\Setting::set('monitor_consist_check', date('Y-m-d H:i:s', time() - 3600));
     $this->assertEquals(array(), Monitor::import_consist_monitor());
     $server = reset($hosts);
     Server::instance($server['host_name'])->getlink()->query(sprintf('DELETE FROM test.test_a ORDER BY id ASC LIMIT 1'));
     \Myfox\App\Setting::set('monitor_consist_check', date('Y-m-d H:i:s', time() - 3600));
     $result = Monitor::import_consist_monitor();
     $this->assertTrue(!empty($result));
     $result = reset($result);
     $this->assertTrue(!empty($result['checks']));
 }
 /**
  * 获取某条分片的信息
  * @param {String} split 路由分片表名
  * @param {String} table 某张具体表的路由信息
  * @return {Array} 此路由分片表中所有的分片信息
  */
 private function get_route_infos($table = '')
 {
     $sql = '';
     if (empty($table)) {
         $sql = sprintf('SELECT autokid,table_name,real_table,hosts_list FROM %s%s 
             WHERE route_flag >= %s AND route_flag < %s AND modtime >= %s', $this->mysql->escape($this->mysql->option('prefix')), $this->routetab, '300', '400', strtotime(Setting::get('unique_last_check')));
     } else {
         $sql = sprintf("SELECT autokid,addtime,real_table,hosts_list FROM %s%s \n                WHERE table_name = '%s' AND route_flag >= %s AND route_flag < %s AND addtime > %s", $this->mysql->escape($this->mysql->option('prefix')), $this->routetab, $this->mysql->escape($table), '300', '400', time() - $this->option['interval']);
     }
     return $this->mysql->getAll($this->mysql->query($sql));
 }
Example #8
0
 /**
  * 计算路由
  *
  * @access private
  * @return Mixture
  */
 private function insert($detail = array())
 {
     if (self::MIRROR == $this->table->get('route_type')) {
         $hosts = self::$hostall;
         $backup = count($hosts);
         $chunks = array(array(array('data' => '', 'size' => empty($detail[0]['count']) ? 0 : $detail[0]['count'])));
     } else {
         $hosts = self::$onlines;
         $backup = min(max(1, $this->table->get('backups')), count(self::$onlines));
         $bucket = new \Myfox\App\Bucket($this->table->get('split_threshold', 2000000), $this->table->get('split_drift', 0.2));
         foreach ((array) $detail as $route) {
             $bucket->push($this->filter($route['field']), $route['count']);
         }
         $chunks = $bucket->allot();
     }
     $counts = count($hosts);
     $skips = max(1, (int) ($counts / $backup));
     $last = (int) Setting::get('last_assign_host');
     $bucket = array();
     $cursor = (int) Setting::get('table_route_count', $this->tbname);
     $dbnums = (int) Setting::get('table_real_count', $this->tbname);
     foreach ($chunks as $items) {
         $ns = array();
         for ($i = 0; $i < $backup; $i++) {
             $ns[] = $hosts[($i * $skips + $last) % $counts];
         }
         $ns = implode(',', $ns);
         $tb = sprintf('%s_%d.t_%d_%d', $this->tbname, $dbnums % self::TABLES_PER_DB, $this->table->get('autokid'), self::MIRROR === $this->table->get('route_type') ? $cursor : $cursor % 3);
         foreach ($items as $it) {
             $bucket[$it['data']][] = array('rows' => $it['size'], 'hosts' => $ns, 'table' => $tb);
         }
         $cursor++;
         $last++;
     }
     Setting::set('last_assign_host', $last % $counts);
     Setting::set('table_route_count', sprintf('IF(cfgvalue + 0 > %d, cfgvalue, %d)', $cursor, $cursor), $this->tbname, false);
     $time = time();
     self::$mysql->begin();
     foreach ($bucket as $key => $slice) {
         $sign = $this->sign($key);
         $key = self::$mysql->escape($key);
         $values = array();
         foreach ($slice as $rt) {
             $values[] = sprintf("(%d,0,%d,%d,'%s','%s','%s\$','%s')", $sign, self::FLAG_PRE_IMPORT, $time, $this->tbname, $key, '', $rt['table']);
         }
         $rt = false !== self::$mysql->query(sprintf("UPDATE %s SET route_flag=IF(route_flag=%d,%d,%d) WHERE route_sign=%u AND table_name='%s' AND route_text='%s'", self::table($sign), self::FLAG_NORMAL_USE, self::FLAG_PRE_RESHIP, self::FLAG_IS_DELETED, $sign, $this->tbname, $key)) && false !== self::$mysql->query(sprintf('INSERT INTO %s (route_sign,is_archive,route_flag,addtime,table_name,route_text,hosts_list,real_table) VALUES %s', self::table($sign), implode(',', $values)));
         if (empty($rt)) {
             self::$mysql->rollback();
             return false;
         }
     }
     self::$mysql->commit();
     return $bucket;
 }
 public function test_add_new_split_works_fine()
 {
     $this->test_set_split_works_fine();
     sleep(3);
     $this->mysql->query(sprintf("insert into %sroute_info (table_name,addtime,modtime,real_table,hosts_list,route_flag) values ('testTable',%s,%s,'meta_myfox_config.test_table_real3','99\$',300)", $this->mysql->option("prefix"), time(), time()));
     $this->mysql->query("insert into test_table_real3 (key1,key2) values ('a',2)");
     $this->mysql->query("insert into test_table_real3 (key1,key2) values ('b',5)");
     $originalModtime = Setting::get('unique_last_check');
     $uniqueBuilder = new \Myfox\App\Worker\Uniquebuilder();
     $uniqueBuilder->execute();
     $res = $this->mysql->getAll($this->mysql->query(sprintf("select unique_key from %sroute_info where table_name = 'testTable' and real_table = 'meta_myfox_config.test_table_real3'", $this->mysql->option("prefix"))));
     $this->assertEquals(array('unique_key' => 'id;key1;key2$'), $res[0]);
     $res = $this->mysql->getAll($this->mysql->query(sprintf("select cfgvalue,modtime from %ssettings where cfgname = 'unique_last_check'", $this->mysql->option("prefix"))));
     $this->assertFalse($originalModtime === $res[0]['modtime']);
 }
Example #10
0
 /**
  * 数据装载一致性监控
  *
  * @access public static
  * @return Mixture
  */
 public static function import_consist_monitor()
 {
     $mysql = \Myfox\Lib\Mysql::instance('default');
     $tables = $mysql->getAll($mysql->query(sprintf("SHOW TABLES LIKE '%sroute_info%%'", $mysql->option('prefix'))));
     $status = array();
     $offset = (int) strtotime(Setting::get('monitor_consist_check'));
     foreach ($tables as $table) {
         $table = end($table);
         $split = $mysql->getAll($mysql->query(sprintf('SELECT real_table,hosts_list,route_text,table_name FROM %s WHERE modtime >= %d AND route_flag IN (%d, %d)', $table, $offset, Router::FLAG_IMPORT_END, Router::FLAG_NORMAL_USE)));
         if (empty($split)) {
             continue;
         }
         foreach ($split as $row) {
             $server = array();
             foreach (explode(',', trim($row['hosts_list'], '{},$')) as $id) {
                 $server[] = self::hostname($id);
             }
             $result = Consist::check($row['real_table'], $server);
             if (is_array($result)) {
                 $status[] = array('table' => $row['table_name'], 'route' => $row['route_text'], 'bucket' => $row['real_table'], 'checks' => $result);
             }
         }
     }
     Setting::set('monitor_consist_check', date('Y-m-d H:i:s'));
     return $status;
 }
Example #11
0
 /**
  * 数据装载状态查询
  *
  * @access protected
  * @return void
  */
 protected function actionIndex($param, $post = null)
 {
     self::output(0, 'OK', json_encode(array('last_date' => \Myfox\App\Setting::get('last_date'))));
 }
Example #12
0
 protected function actionLastdate($param)
 {
     echo json_encode(array('group_name' => '__global__', 'last_date' => \Myfox\App\Setting::get('myfox_last_date')));
 }
 public function test_should_ready_task_works_fine()
 {
     $task = new \Myfox\App\Task\Ready(-1, array());
     $this->assertEquals(Task::IGNO, $task->execute());
     \Myfox\App\Setting::set('last_date', '2011-10-01');
     $task = new \Myfox\App\Task\Ready(-1, array('thedate' => '2011-10-01', 'priority' => 1));
     $this->assertEquals(Task::IGNO, $task->execute());
     self::$mysql->query(sprintf('TRUNCATE TABLE %stask_queque', self::$mysql->option('prefix')));
     self::$mysql->query(sprintf('INSERT INTO %stask_queque (autokid,priority,task_flag,task_type) VALUES ' . "(1,21,%d,'import'),(2,20,%d,'import'),(3,20,%d,'import'),(4,19,%d,'lalallala'),(101,1,%d,'import')", self::$mysql->option('prefix'), \Myfox\App\Queque::FLAG_WAIT, \Myfox\App\Queque::FLAG_NEW, \Myfox\App\Queque::FLAG_IGNO, \Myfox\App\Queque::FLAG_LOCK, \Myfox\App\Queque::FLAG_WAIT));
     \Myfox\App\Setting::set('last_date', '2011-10-01');
     $task = new \Myfox\App\Task\Ready(100, array('thedate' => '2011-10-02', 'priority' => 20));
     $this->assertEquals(Task::FAIL, $task->execute());
     $this->assertContains('Waiting for 1 import task(s)', $task->lastError());
     self::$mysql->query(sprintf('TRUNCATE TABLE %stask_queque', self::$mysql->option('prefix')));
     \Myfox\App\Setting::set('last_date', '2011-10-01');
     $task = new \Myfox\App\Task\Ready(100, array('thedate' => '2011-10-02', 'priority' => 20));
     $this->assertEquals(Task::SUCC, $task->execute());
 }