00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <plugin/slave/replication_slave.h>
00023 #include <drizzled/errmsg_print.h>
00024 #include <drizzled/program_options/config_file.h>
00025 #include <boost/lexical_cast.hpp>
00026 #include <boost/program_options.hpp>
00027 #include <fstream>
00028 #include <drizzled/plugin.h>
00029
00030 using namespace std;
00031 using namespace drizzled;
00032
00033 namespace po= boost::program_options;
00034
00035 namespace slave
00036 {
00037
00038 void ReplicationSlave::startup(Session &session)
00039 {
00040 (void)session;
00041 if (not initWithConfig())
00042 {
00043 errmsg_printf(error::ERROR, _("Could not start slave services: %s\n"),
00044 _error.c_str());
00045 }
00046 else
00047 {
00048
00049 boost::unordered_map<uint32_t, Master *>::const_iterator it;
00050 for (it= _masters.begin(); it != _masters.end(); ++it)
00051 {
00052 it->second->start();
00053
00054 _consumer.addMasterId(it->first);
00055 }
00056
00057 _consumer_thread= boost::thread(&QueueConsumer::run, &_consumer);
00058 }
00059 }
00060
00061 bool ReplicationSlave::initWithConfig()
00062 {
00063 po::variables_map vm;
00064 po::options_description slave_options("Options for the slave plugin");
00065
00066
00067 slave_options.add_options()
00068 ("seconds-between-reconnects", po::value<uint32_t>()->default_value(30))
00069 ("io-thread-sleep", po::value<uint32_t>()->default_value(5))
00070 ("applier-thread-sleep", po::value<uint32_t>()->default_value(5))
00071 ("ignore-errors", po::value<bool>()->default_value(false)->zero_tokens());
00072
00073
00074 for (size_t num= 1; num <= 10; num++)
00075 {
00076 string section("master");
00077 section.append(boost::lexical_cast<string>(num));
00078 slave_options.add_options()
00079 ((section + ".master-host").c_str(), po::value<string>()->default_value(""))
00080 ((section + ".master-port").c_str(), po::value<uint16_t>()->default_value(3306))
00081 ((section + ".master-user").c_str(), po::value<string>()->default_value(""))
00082 ((section + ".master-pass").c_str(), po::value<string>()->default_value(""))
00083 ((section + ".max-reconnects").c_str(), po::value<uint32_t>()->default_value(10))
00084 ((section + ".max-commit-id").c_str(), po::value<uint64_t>());
00085 }
00086
00087 ifstream cf_stream(_config_file.c_str());
00088
00089 if (not cf_stream.is_open())
00090 {
00091 _error= "Unable to open file ";
00092 _error.append(_config_file);
00093 return false;
00094 }
00095
00096 po::store(drizzled::program_options::parse_config_file(cf_stream, slave_options), vm);
00097
00098 po::notify(vm);
00099
00100
00101
00102
00103
00104
00105
00106 for (size_t num= 1; num <= 10; num++)
00107 {
00108 string section("master");
00109 section.append(boost::lexical_cast<string>(num));
00110
00111
00112
00113
00114
00115
00116
00117 if (vm[section + ".master-host"].as<string>() == "")
00118 continue;
00119
00120 _masters[num]= new (std::nothrow) Master(num);
00121
00122 if (vm.count(section + ".master-host"))
00123 master(num).producer().setMasterHost(vm[section + ".master-host"].as<string>());
00124
00125 if (vm.count(section + ".master-port"))
00126 master(num).producer().setMasterPort(vm[section + ".master-port"].as<uint16_t>());
00127
00128 if (vm.count(section + ".master-user"))
00129 master(num).producer().setMasterUser(vm[section + ".master-user"].as<string>());
00130
00131 if (vm.count(section + ".master-pass"))
00132 master(num).producer().setMasterPassword(vm[section + ".master-pass"].as<string>());
00133
00134 if (vm.count(section + ".max-commit-id"))
00135 master(num).producer().setCachedMaxCommitId(vm[section + ".max-commit-id"].as<uint64_t>());
00136 }
00137
00138 boost::unordered_map<uint32_t, Master *>::const_iterator it;
00139
00140 for (it= _masters.begin(); it != _masters.end(); ++it)
00141 {
00142 if (vm.count("max-reconnects"))
00143 it->second->producer().setMaxReconnectAttempts(vm["max-reconnects"].as<uint32_t>());
00144
00145 if (vm.count("seconds-between-reconnects"))
00146 it->second->producer().setSecondsBetweenReconnects(vm["seconds-between-reconnects"].as<uint32_t>());
00147
00148 if (vm.count("io-thread-sleep"))
00149 it->second->producer().setSleepInterval(vm["io-thread-sleep"].as<uint32_t>());
00150 }
00151
00152 if (vm.count("applier-thread-sleep"))
00153 _consumer.setSleepInterval(vm["applier-thread-sleep"].as<uint32_t>());
00154 if (vm.count("ignore-errors"))
00155 _consumer.setIgnoreErrors(vm["ignore-errors"].as<bool>());
00156
00157
00158 ReplicationSchema rs;
00159 if (not rs.create())
00160 {
00161 _error= rs.getErrorMessage();
00162 return false;
00163 }
00164
00165 for (it= _masters.begin(); it != _masters.end(); ++it)
00166 {
00167
00168 rs.createInitialApplierRow(it->first);
00169 rs.createInitialIORow(it->first);
00170
00171 uint64_t cachedValue= it->second->producer().cachedMaxCommitId();
00172 if (cachedValue)
00173 {
00174 if (not rs.setInitialMaxCommitId(it->first, cachedValue))
00175 {
00176 _error= rs.getErrorMessage();
00177 return false;
00178 }
00179 }
00180 }
00181
00182 return true;
00183 }
00184
00185 }