Beispiel #1
0
def initial_reparent(keyspace, master_cell, num_shards, namespace):
  """Performs the first reparent."""
  successfully_reparented = []
  master_tablets = {}
  while len(master_tablets) < num_shards:
    for shard_name in sharding_utils.get_shard_names(num_shards):
      shard_name = sandbox_utils.fix_shard_name(shard_name)
      tablets = vtctl_sandbox.execute_vtctl_command(
          ['ListShardTablets', '%s/%s' % (
              keyspace, sandbox_utils.fix_shard_name(shard_name))],
          namespace=namespace)[0].split('\n')
      tablets = [x.split(' ') for x in tablets if x]
      potential_masters = [
          x[0] for x in tablets if x[3] == 'replica'
          and x[0].split('-')[0] == master_cell]
      if potential_masters:
        master_tablets[shard_name] = potential_masters[0]

  while len(successfully_reparented) < num_shards:
    for shard_name in sharding_utils.get_shard_names(num_shards):
      shard_name = sandbox_utils.fix_shard_name(shard_name)
      master_tablet_id = master_tablets[shard_name]
      if is_master(master_tablet_id, namespace):
        logging.info('Tablet %s is the master of %s/%s.',
                     master_tablet_id, keyspace, shard_name)
        successfully_reparented.append(shard_name)
      if shard_name in successfully_reparented:
        continue
      logging.info('Setting tablet %s as master for %s/%s.',
                   master_tablet_id, keyspace, shard_name)
      vtctl_sandbox.execute_vtctl_command(
          ['InitShardMaster', '-force', '%s/%s' % (keyspace, shard_name),
           master_tablet_id], namespace=namespace, timeout_s=5)
  logging.info('Done with initial reparent.')
def initial_reparent(keyspace, master_cell, num_shards, namespace, timeout_s):
    """Performs the first reparent."""
    successfully_reparented = []
    master_tablets = {}
    start_time = time.time()
    logging.info('Finding tablets to reparent to.')
    while len(master_tablets) < num_shards:
        if time.time() - start_time > timeout_s:
            logging.error('Timed out waiting to find a replica tablet')
            return 1

        for shard_name in sharding_utils.get_shard_names(num_shards):
            if shard_name in master_tablets:
                continue
            tablets = vtctl_sandbox.execute_vtctl_command(
                ['ListShardTablets',
                 '%s/%s' % (keyspace, shard_name)],
                namespace=namespace)[0].split('\n')
            tablets = [x.split(' ') for x in tablets if x]
            potential_masters = [
                x[0] for x in tablets
                if x[3] == 'replica' and x[0].split('-')[0] == master_cell
            ]
            if potential_masters:
                master_tablets[shard_name] = potential_masters[0]
                logging.info('%s selected for shard %s', potential_masters[0],
                             shard_name)

    while time.time() - start_time < timeout_s:
        for shard_name in sharding_utils.get_shard_names(num_shards):
            master_tablet_id = master_tablets[shard_name]
            if is_master(master_tablet_id, namespace):
                logging.info('Tablet %s is the master of %s/%s.',
                             master_tablet_id, keyspace, shard_name)
                successfully_reparented.append(shard_name)
            if shard_name in successfully_reparented:
                continue
            logging.info('Setting tablet %s as master for %s/%s.',
                         master_tablet_id, keyspace, shard_name)
            vtctl_sandbox.execute_vtctl_command([
                'InitShardMaster', '-force',
                '%s/%s' % (keyspace, shard_name), master_tablet_id
            ],
                                                namespace=namespace,
                                                timeout_s=5)
        if len(successfully_reparented) == num_shards:
            logging.info('Done with initial reparent.')
            return 0

    logging.error('Timed out waiting for initial reparent.')
    return 1
Beispiel #3
0
def main(cmdline_options):
    topology = vttest_pb2.VTTestTopology()
    if cmdline_options.proto_topo:
        # Text-encoded proto topology object, just parse it.
        topology = text_format.Parse(cmdline_options.proto_topo, topology)
        if not topology.cells:
            topology.cells.append('test')
    else:
        cells = []
        keyspaces = []
        shard_counts = []
        if cmdline_options.cells:
            cells = cmdline_options.cells.split(',')
        if cmdline_options.keyspaces:
            keyspaces = cmdline_options.keyspaces.split(',')
        if cmdline_options.num_shards:
            shard_counts = [
                int(x) for x in cmdline_options.num_shards.split(',')
            ]

        for cell in cells:
            topology.cells.append(cell)
        for keyspace, num_shards in zip(keyspaces, shard_counts):
            ks = topology.keyspaces.add(name=keyspace)
            for shard in sharding_utils.get_shard_names(num_shards):
                ks.shards.add(name=shard)
            ks.replica_count = cmdline_options.replica_count
            ks.rdonly_count = cmdline_options.rdonly_count

    environment.base_port = cmdline_options.port

    init_data_opts = None
    if cmdline_options.initialize_with_random_data:
        init_data_opts = init_data_options.InitDataOptions()
        init_data_opts.rng_seed = cmdline_options.rng_seed
        init_data_opts.min_table_shard_size = cmdline_options.min_table_shard_size
        init_data_opts.max_table_shard_size = cmdline_options.max_table_shard_size
        init_data_opts.null_probability = cmdline_options.null_probability

    with local_database.LocalDatabase(
            topology,
            cmdline_options.schema_dir,
            cmdline_options.mysql_only,
            init_data_opts,
            web_dir=cmdline_options.web_dir,
            web_dir2=cmdline_options.web_dir2,
            default_schema_dir=cmdline_options.default_schema_dir,
            extra_my_cnf=os.path.join(os.environ['VTTOP'],
                                      'config/mycnf/vtcombo.cnf')) as local_db:
        print json.dumps(local_db.config())
        sys.stdout.flush()
        try:
            raw_input()
        except EOFError:
            sys.stderr.write(
                'WARNING: %s: No empty line was received on stdin.'
                ' Instead, stdin was closed and the cluster will be shut down now.'
                ' Make sure to send the empty line instead to proactively shutdown'
                ' the local cluster. For example, did you forget the shutdown in'
                ' your test\'s tearDown()?\n' % os.path.basename(__file__))
Beispiel #4
0
  def setUp(self):
    """Updates schema, adding a table and populating it with data."""
    super(BackupTest, self).setUp()
    os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
    os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
    self.table_name = 'vt_insert_test'

    self.env.delete_table(self.table_name)
    self.env.create_table(self.table_name, validate_deadline_s=120)

    for keyspace, num_shards in zip(self.env.keyspaces, self.env.num_shards):
      for shard_name in sharding_utils.get_shard_names(num_shards):
        logging.info('Inserting %d rows into %s',
                     self.num_inserts, self.table_name)
        kr = keyrange.KeyRange('') if num_shards == 1 else keyrange.KeyRange(
            shard_name)

        master_tablet = self.env.get_current_master_name(keyspace, shard_name)
        master_cell = self.env.get_tablet_cell(master_tablet)
        conn = self.env.get_vtgate_conn(master_cell)
        cursor = conn.cursor(tablet_type='master', keyspace=keyspace,
                             keyranges=[kr], writable=True)
        for i in xrange(self.num_inserts):
          cursor.begin()
          cursor.execute(
              'insert into %s (msg, keyspace_id) values (:msg, :keyspace_id)' %
              self.table_name, {'msg': 'test %d' % i, 'keyspace_id': 0})
          cursor.commit()
        cursor.close()
        logging.info('Data insertion complete')
Beispiel #5
0
  def setUp(self):
    """Updates schema, adding a table and populating it with data."""
    super(BackupTest, self).setUp()
    os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
    os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
    self.table_name = 'vt_insert_test'

    self.env.delete_table(self.table_name)
    self.env.create_table(self.table_name, validate_deadline_s=120)

    for keyspace, num_shards in zip(self.env.keyspaces, self.env.num_shards):
      for shard_name in sharding_utils.get_shard_names(num_shards):
        logging.info('Inserting %d rows into %s',
                     self.num_inserts, self.table_name)
        kr = keyrange.KeyRange('') if num_shards == 1 else keyrange.KeyRange(
            shard_name)

        master_tablet = self.env.get_current_master_name(keyspace, shard_name)
        master_cell = self.env.get_tablet_cell(master_tablet)
        conn = self.env.get_vtgate_conn(master_cell)
        cursor = conn.cursor(tablet_type='master', keyspace=keyspace,
                             keyranges=[kr], writable=True)
        for i in xrange(self.num_inserts):
          cursor.begin()
          cursor.execute(
              'insert into %s (msg, keyspace_id) values (:msg, :keyspace_id)' %
              self.table_name, {'msg': 'test %d' % i, 'keyspace_id': 0})
          cursor.commit()
        cursor.close()
        logging.info('Data insertion complete')
def main(cmdline_options):
    topology = vttest_pb2.VTTestTopology()
    if cmdline_options.proto_topo:
        # Text-encoded proto topology object, just parse it.
        topology = text_format.Parse(cmdline_options.proto_topo, topology)
        if not topology.cells:
            topology.cells.append("test")
    else:
        cells = []
        keyspaces = []
        shard_counts = []
        if cmdline_options.cells:
            cells = cmdline_options.cells.split(",")
        if cmdline_options.keyspaces:
            keyspaces = cmdline_options.keyspaces.split(",")
        if cmdline_options.num_shards:
            shard_counts = [int(x) for x in cmdline_options.num_shards.split(",")]

        for cell in cells:
            topology.cells.append(cell)
        for keyspace, num_shards in zip(keyspaces, shard_counts):
            ks = topology.keyspaces.add(name=keyspace)
            for shard in sharding_utils.get_shard_names(num_shards):
                ks.shards.add(name=shard)
            ks.replica_count = cmdline_options.replica_count
            ks.rdonly_count = cmdline_options.rdonly_count

    environment.base_port = cmdline_options.port

    init_data_opts = None
    if cmdline_options.initialize_with_random_data:
        init_data_opts = init_data_options.InitDataOptions()
        init_data_opts.rng_seed = cmdline_options.rng_seed
        init_data_opts.min_table_shard_size = cmdline_options.min_table_shard_size
        init_data_opts.max_table_shard_size = cmdline_options.max_table_shard_size
        init_data_opts.null_probability = cmdline_options.null_probability

    with local_database.LocalDatabase(
        topology,
        cmdline_options.schema_dir,
        cmdline_options.mysql_only,
        init_data_opts,
        web_dir=cmdline_options.web_dir,
        web_dir2=cmdline_options.web_dir2,
        default_schema_dir=cmdline_options.default_schema_dir,
        extra_my_cnf=os.path.join(os.environ["VTTOP"], "config/mycnf/vtcombo.cnf"),
    ) as local_db:
        print json.dumps(local_db.config())
        sys.stdout.flush()
        try:
            raw_input()
        except EOFError:
            sys.stderr.write(
                "WARNING: %s: No empty line was received on stdin."
                " Instead, stdin was closed and the cluster will be shut down now."
                " Make sure to send the empty line instead to proactively shutdown"
                " the local cluster. For example, did you forget the shutdown in"
                " your test's tearDown()?\n" % os.path.basename(__file__)
            )
Beispiel #7
0
def initial_reparent(keyspace, master_cell, num_shards, namespace, timeout_s):
  """Performs the first reparent."""
  successfully_reparented = []
  master_tablets = {}
  start_time = time.time()
  logging.info('Finding tablets to reparent to.')
  while len(master_tablets) < num_shards:
    if time.time() - start_time > timeout_s:
      logging.error('Timed out waiting to find a replica tablet')
      return 1

    for shard_name in sharding_utils.get_shard_names(num_shards):
      if shard_name in master_tablets:
        continue
      tablets = vtctl_sandbox.execute_vtctl_command(
          ['ListShardTablets', '%s/%s' % (keyspace, shard_name)],
          namespace=namespace)[0].split('\n')
      tablets = [x.split(' ') for x in tablets if x]
      potential_masters = [
          x[0] for x in tablets if x[3] == 'replica'
          and x[0].split('-')[0] == master_cell]
      if potential_masters:
        master_tablets[shard_name] = potential_masters[0]
        logging.info(
            '%s selected for shard %s', potential_masters[0], shard_name)

  while time.time() - start_time < timeout_s:
    for shard_name in sharding_utils.get_shard_names(num_shards):
      master_tablet_id = master_tablets[shard_name]
      if is_master(master_tablet_id, namespace):
        logging.info('Tablet %s is the master of %s/%s.',
                     master_tablet_id, keyspace, shard_name)
        successfully_reparented.append(shard_name)
      if shard_name in successfully_reparented:
        continue
      logging.info('Setting tablet %s as master for %s/%s.',
                   master_tablet_id, keyspace, shard_name)
      vtctl_sandbox.execute_vtctl_command(
          ['InitShardMaster', '-force', '%s/%s' % (keyspace, shard_name),
           master_tablet_id], namespace=namespace, timeout_s=5)
    if len(successfully_reparented) == num_shards:
      logging.info('Done with initial reparent.')
      return 0

  logging.error('Timed out waiting for initial reparent.')
  return 1
Beispiel #8
0
 def tearDownClass(cls):
   for keyspace, num_shards in zip(cls.env.keyspaces, cls.env.num_shards):
     for shard_name in sharding_utils.get_shard_names(num_shards):
       drained_tablets = [x[0] for x in cls.env.get_tablet_types_for_shard(
           keyspace, shard_name) if x[1] == 'drained']
       for tablet in drained_tablets:
         logging.info('Undraining tablet %s', tablet)
         cls.env.undrain_tablet(tablet)
 def tearDownClass(cls):
   for keyspace, num_shards in zip(cls.env.keyspaces, cls.env.num_shards):
     for shard_name in sharding_utils.get_shard_names(num_shards):
       drained_tablets = [x[0] for x in cls.env.get_tablet_types_for_shard(
           keyspace, shard_name) if x[1] == 'drained']
       for tablet in drained_tablets:
         logging.info('Undraining tablet %s', tablet)
         cls.env.undrain_tablet(tablet)
Beispiel #10
0
def initial_reparent(keyspace, master_cell, num_shards, namespace):
    """Performs the first reparent."""
    successfully_reparented = []
    master_tablets = {}
    while len(master_tablets) < num_shards:
        for shard_name in sharding_utils.get_shard_names(num_shards):
            shard_name = sandbox_utils.fix_shard_name(shard_name)
            tablets = vtctl_sandbox.execute_vtctl_command(
                [
                    'ListShardTablets',
                    '%s/%s' %
                    (keyspace, sandbox_utils.fix_shard_name(shard_name))
                ],
                namespace=namespace)[0].split('\n')
            tablets = [x.split(' ') for x in tablets if x]
            potential_masters = [
                x[0] for x in tablets
                if x[3] == 'replica' and x[0].split('-')[0] == master_cell
            ]
            if potential_masters:
                master_tablets[shard_name] = potential_masters[0]

    while len(successfully_reparented) < num_shards:
        for shard_name in sharding_utils.get_shard_names(num_shards):
            shard_name = sandbox_utils.fix_shard_name(shard_name)
            master_tablet_id = master_tablets[shard_name]
            if is_master(master_tablet_id, namespace):
                logging.info('Tablet %s is the master of %s/%s.',
                             master_tablet_id, keyspace, shard_name)
                successfully_reparented.append(shard_name)
            if shard_name in successfully_reparented:
                continue
            logging.info('Setting tablet %s as master for %s/%s.',
                         master_tablet_id, keyspace, shard_name)
            vtctl_sandbox.execute_vtctl_command([
                'InitShardMaster', '-force',
                '%s/%s' % (keyspace, shard_name), master_tablet_id
            ],
                                                namespace=namespace,
                                                timeout_s=5)
    logging.info('Done with initial reparent.')
  def get_all_tablet_types(self, keyspace, num_shards):
    """Get the types for all tablets in a keyspace.

    Args:
      keyspace: Name of keyspace to get tablet information on (string).
      num_shards: number of shards in the keyspace (int).

    Returns:
      List of pairs of tablet's name and type.
    """
    tablet_info = []
    for shard_name in sharding_utils.get_shard_names(num_shards):
      tablet_info += self.get_tablet_types_for_shard(keyspace, shard_name)
    return tablet_info
  def use_named(self, instance_name):
    """Populate this instance based on a pre-existing environment.

    Args:
      instance_name: Name of the existing environment instance (string).
    """
    self.master_capable_tablets = {}
    for keyspace, num_shards in zip(self.keyspaces, self.num_shards):
      self.master_capable_tablets[keyspace] = {}
      for shard_name in sharding_utils.get_shard_names(num_shards):
        raw_shard_tablets = self.vtctl_helper.execute_vtctl_command(
            ['ListShardTablets', '%s/%s' % (keyspace, shard_name)])
        split_shard_tablets = [
            t.split(' ') for t in raw_shard_tablets.split('\n') if t]
        self.master_capable_tablets[keyspace][shard_name] = [
            t[0] for t in split_shard_tablets
            if (self.get_tablet_cell(t[0]) in self.primary_cells
                and (t[3] == 'master' or t[3] == 'replica'))]
Beispiel #13
0
  def _generate_helm_keyspaces(self):
    """Create helm keyspace configurations.

    These configurations include entries for keyspaces, shards, and tablets.
    Note that the logic for calculating UIDs will go away once Kubernetes 1.5
    is widely available. Then tablets will use replication controllers with
    StatefulSet, and UIDs will be calculated automatically.

    Returns:
      Configuration for keyspaces in the form of a list of dicts.
    """
    starting_cell_index = 0
    if len(self.app_options.cells) > 1:
      starting_cell_index = self.cell_epsilon
    keyspaces = []
    for ks_index, ks in enumerate(self.app_options.keyspaces):
      keyspace = dict(name=ks['name'], shards=[])
      keyspaces.append(keyspace)

      for shard_index, shard_name in enumerate(
          sharding_utils.get_shard_names(ks['shard_count'])):
        shard = dict(
            name=shard_name,
            tablets=[dict(
                type='replica',
                vttablet=dict(
                    replicas=ks['replica_count'],
                ),
            )],
        )
        uid_base = (
            (100 + shard_index * self.shard_epsilon) + starting_cell_index + (
                ks_index * self.keyspace_epsilon))
        shard['tablets'][0]['uidBase'] = uid_base
        if ks['rdonly_count']:
          shard['tablets'].append(dict(
              type='rdonly',
              uidBase=uid_base + ks['replica_count'],
              vttablet=dict(
                  replicas=ks['rdonly_count'],
              )))
        keyspace['shards'].append(shard)
    return keyspaces