mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge bk-internal.mysql.com:/data0/bk/mysql-5.1-new
into bk-internal.mysql.com:/data0/bk/mysql-5.1-kt include/m_string.h: Auto merged include/my_sys.h: Auto merged mysql-test/mysql-test-run.pl: Auto merged sql/log.cc: Auto merged sql/mysqld.cc: Auto merged sql/set_var.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/share/errmsg.txt: C Merged. ?
This commit is contained in:
@@ -1770,3 +1770,4 @@ vio/viotest-sslconnect.cpp
|
||||
vio/viotest.cpp
|
||||
zlib/*.ds?
|
||||
zlib/*.vcproj
|
||||
libmysqld/event_scheduler.cc
|
||||
|
@@ -64,7 +64,7 @@
|
||||
/* were just going to fake it here and get input from
|
||||
the keyboard */
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
char *get_tty_password(const char *opt_message)
|
||||
{
|
||||
char to[80];
|
||||
char *pos=to,*end=to+sizeof(to)-1;
|
||||
@@ -150,7 +150,7 @@ static void get_password(char *to,uint length,int fd,bool echo)
|
||||
#endif /* ! HAVE_GETPASS */
|
||||
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
char *get_tty_password(const char *opt_message)
|
||||
{
|
||||
#ifdef HAVE_GETPASS
|
||||
char *passbuff;
|
||||
|
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
|
||||
AC_CANONICAL_SYSTEM
|
||||
# The Docs Makefile.am parses this line!
|
||||
# remember to also change ndb version below and update version.c in ndb
|
||||
AM_INIT_AUTOMAKE(mysql, 5.1.11-beta)
|
||||
AM_INIT_AUTOMAKE(mysql, 5.1.12-beta)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
PROTOCOL_VERSION=10
|
||||
|
@@ -65,7 +65,8 @@ THREAD_RETURN YASSL_API echoserver_test(void* args)
|
||||
while (!shutdown) {
|
||||
sockaddr_in client;
|
||||
socklen_t client_len = sizeof(client);
|
||||
int clientfd = accept(sockfd, (sockaddr*)&client, &client_len);
|
||||
int clientfd = accept(sockfd, (sockaddr*)&client,
|
||||
(ACCEPT_THIRD_T)&client_len);
|
||||
if (clientfd == -1) err_sys("tcp accept failed");
|
||||
|
||||
SSL* ssl = SSL_new(ctx);
|
||||
|
@@ -273,6 +273,7 @@ int SSL_pending(SSL*);
|
||||
|
||||
|
||||
enum { /* ssl Constants */
|
||||
SSL_WOULD_BLOCK = -8,
|
||||
SSL_BAD_STAT = -7,
|
||||
SSL_BAD_PATH = -6,
|
||||
SSL_BAD_FILETYPE = -5,
|
||||
@@ -494,7 +495,7 @@ ASN1_TIME* X509_get_notAfter(X509* x);
|
||||
|
||||
|
||||
typedef struct MD4_CTX {
|
||||
void* ptr;
|
||||
int buffer[32]; /* big enough to hold, check size in Init */
|
||||
} MD4_CTX;
|
||||
|
||||
void MD4_Init(MD4_CTX*);
|
||||
|
@@ -66,6 +66,7 @@ typedef unsigned char byte;
|
||||
// Wraps Windows Sockets and BSD Sockets
|
||||
class Socket {
|
||||
socket_t socket_; // underlying socket descriptor
|
||||
bool wouldBlock_; // for non-blocking data
|
||||
public:
|
||||
explicit Socket(socket_t s = INVALID_SOCKET);
|
||||
~Socket();
|
||||
@@ -75,9 +76,10 @@ public:
|
||||
socket_t get_fd() const;
|
||||
|
||||
uint send(const byte* buf, unsigned int len, int flags = 0) const;
|
||||
uint receive(byte* buf, unsigned int len, int flags = 0) const;
|
||||
uint receive(byte* buf, unsigned int len, int flags = 0);
|
||||
|
||||
bool wait() const;
|
||||
bool wait();
|
||||
bool WouldBlock() const;
|
||||
|
||||
void closeSocket();
|
||||
void shutDown(int how = SD_SEND);
|
||||
|
@@ -46,8 +46,10 @@ public:
|
||||
// for compiler generated call, never used
|
||||
static void operator delete(void*) { assert(0); }
|
||||
private:
|
||||
#if defined(__hpux)
|
||||
// don't allow dynamic creation of exceptions
|
||||
static void* operator new(size_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@@ -656,7 +656,7 @@ mySTL::auto_ptr<input_buffer>
|
||||
DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
||||
{
|
||||
// wait for input if blocking
|
||||
if (!ssl.getSocket().wait()) {
|
||||
if (!ssl.useSocket().wait()) {
|
||||
ssl.SetError(receive_error);
|
||||
buffered.reset(0);
|
||||
return buffered;
|
||||
@@ -673,7 +673,7 @@ DoProcessReply(SSL& ssl, mySTL::auto_ptr<input_buffer> buffered)
|
||||
}
|
||||
|
||||
// add new data
|
||||
uint read = ssl.getSocket().receive(buffer.get_buffer() + buffSz, ready);
|
||||
uint read = ssl.useSocket().receive(buffer.get_buffer() + buffSz, ready);
|
||||
buffer.add_size(read);
|
||||
uint offset = 0;
|
||||
const MessageFactory& mf = ssl.getFactory().getMessage();
|
||||
@@ -858,6 +858,9 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer)
|
||||
// send data
|
||||
int sendData(SSL& ssl, const void* buffer, int sz)
|
||||
{
|
||||
if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ))
|
||||
ssl.SetError(no_error);
|
||||
|
||||
ssl.verfiyHandShakeComplete();
|
||||
if (ssl.GetError()) return 0;
|
||||
int sent = 0;
|
||||
@@ -893,6 +896,9 @@ int sendAlert(SSL& ssl, const Alert& alert)
|
||||
// process input data
|
||||
int receiveData(SSL& ssl, Data& data)
|
||||
{
|
||||
if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ))
|
||||
ssl.SetError(no_error);
|
||||
|
||||
ssl.verfiyHandShakeComplete();
|
||||
if (ssl.GetError()) return 0;
|
||||
|
||||
@@ -902,6 +908,11 @@ int receiveData(SSL& ssl, Data& data)
|
||||
ssl.useLog().ShowData(data.get_length());
|
||||
|
||||
if (ssl.GetError()) return 0;
|
||||
|
||||
if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) {
|
||||
ssl.SetError(YasslError(SSL_ERROR_WANT_READ));
|
||||
return SSL_WOULD_BLOCK;
|
||||
}
|
||||
return data.get_length();
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,7 @@ namespace yaSSL {
|
||||
|
||||
|
||||
Socket::Socket(socket_t s)
|
||||
: socket_(s)
|
||||
: socket_(s), wouldBlock_(false)
|
||||
{}
|
||||
|
||||
|
||||
@@ -123,17 +123,21 @@ uint Socket::send(const byte* buf, unsigned int sz, int flags) const
|
||||
}
|
||||
|
||||
|
||||
uint Socket::receive(byte* buf, unsigned int sz, int flags) const
|
||||
uint Socket::receive(byte* buf, unsigned int sz, int flags)
|
||||
{
|
||||
assert(socket_ != INVALID_SOCKET);
|
||||
wouldBlock_ = false;
|
||||
|
||||
int recvd = ::recv(socket_, reinterpret_cast<char *>(buf), sz, flags);
|
||||
|
||||
// idea to seperate error from would block by arnetheduck@gmail.com
|
||||
if (recvd == -1) {
|
||||
if (get_lastError() == SOCKET_EWOULDBLOCK ||
|
||||
get_lastError() == SOCKET_EAGAIN)
|
||||
get_lastError() == SOCKET_EAGAIN) {
|
||||
wouldBlock_ = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (recvd == 0)
|
||||
return static_cast<uint>(-1);
|
||||
|
||||
@@ -142,7 +146,7 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags) const
|
||||
|
||||
|
||||
// wait if blocking for input, return false for error
|
||||
bool Socket::wait() const
|
||||
bool Socket::wait()
|
||||
{
|
||||
byte b;
|
||||
return receive(&b, 1, MSG_PEEK) != static_cast<uint>(-1);
|
||||
@@ -166,6 +170,12 @@ int Socket::get_lastError()
|
||||
}
|
||||
|
||||
|
||||
bool Socket::WouldBlock() const
|
||||
{
|
||||
return wouldBlock_;
|
||||
}
|
||||
|
||||
|
||||
void Socket::set_lastError(int errorCode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "handshake.hpp"
|
||||
#include "yassl_int.hpp"
|
||||
#include "md5.hpp" // for TaoCrypt MD5 size assert
|
||||
#include "md4.hpp" // for TaoCrypt MD4 size assert
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1131,17 +1132,26 @@ void* X509_get_ext_d2i(X509* x, int nid, int* crit, int* idx)
|
||||
|
||||
void MD4_Init(MD4_CTX* md4)
|
||||
{
|
||||
assert(0); // not yet supported, build compat. only
|
||||
// make sure we have a big enough buffer
|
||||
typedef char ok[sizeof(md4->buffer) >= sizeof(TaoCrypt::MD4) ? 1 : -1];
|
||||
(void) sizeof(ok);
|
||||
|
||||
// using TaoCrypt since no dynamic memory allocated
|
||||
// and no destructor will be called
|
||||
new (reinterpret_cast<yassl_pointer>(md4->buffer)) TaoCrypt::MD4();
|
||||
}
|
||||
|
||||
|
||||
void MD4_Update(MD4_CTX* md4, const void* data, unsigned long sz)
|
||||
{
|
||||
reinterpret_cast<TaoCrypt::MD4*>(md4->buffer)->Update(
|
||||
static_cast<const byte*>(data), static_cast<unsigned int>(sz));
|
||||
}
|
||||
|
||||
|
||||
void MD4_Final(unsigned char* hash, MD4_CTX* md4)
|
||||
{
|
||||
reinterpret_cast<TaoCrypt::MD4*>(md4->buffer)->Final(hash);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "hmac.hpp"
|
||||
#include "md5.hpp"
|
||||
#include "sha.hpp"
|
||||
#include "ripemd.hpp"
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
|
@@ -26,13 +26,17 @@
|
||||
#include "runtime.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
static bool init(false);
|
||||
@@ -57,8 +61,6 @@ namespace yaSSL {
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "runtime.hpp"
|
||||
#include "yassl_error.hpp"
|
||||
#include "error.hpp" // TaoCrypt error numbers
|
||||
#include "openssl/ssl.h" // SSL_ERROR_WANT_READ
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
@@ -117,6 +118,11 @@ void SetErrorString(YasslError error, char* buffer)
|
||||
strncpy(buffer, "unable to proccess cerificate", max);
|
||||
break;
|
||||
|
||||
// openssl errors
|
||||
case SSL_ERROR_WANT_READ :
|
||||
strncpy(buffer, "the read operation would block", max);
|
||||
break;
|
||||
|
||||
// TaoCrypt errors
|
||||
case NO_ERROR :
|
||||
strncpy(buffer, "not in error state", max);
|
||||
|
@@ -1415,15 +1415,6 @@ BulkCipher* CryptProvider::NewDesEde()
|
||||
}
|
||||
|
||||
|
||||
extern "C" void yaSSL_CleanUp()
|
||||
{
|
||||
TaoCrypt::CleanUp();
|
||||
ysDelete(cryptProviderInstance);
|
||||
ysDelete(sslFactoryInstance);
|
||||
ysDelete(sessionsInstance);
|
||||
}
|
||||
|
||||
|
||||
typedef Mutex::Lock Lock;
|
||||
|
||||
|
||||
@@ -2109,9 +2100,18 @@ ASN1_STRING* StringHolder::GetString()
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
extern "C" void yaSSL_CleanUp()
|
||||
{
|
||||
TaoCrypt::CleanUp();
|
||||
ysDelete(yaSSL::cryptProviderInstance);
|
||||
ysDelete(yaSSL::sslFactoryInstance);
|
||||
ysDelete(yaSSL::sessionsInstance);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace mySTL {
|
||||
template yaSSL::yassl_int_cpp_local1::SumData for_each<mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData>(mySTL::list<yaSSL::input_buffer*>::iterator, mySTL::list<yaSSL::input_buffer*>::iterator, yaSSL::yassl_int_cpp_local1::SumData);
|
||||
|
@@ -2,7 +2,7 @@ INCLUDE_DIRECTORIES(../mySTL include)
|
||||
|
||||
ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp
|
||||
src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp
|
||||
src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp
|
||||
src/md4.cpp src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp
|
||||
include/aes.hpp include/algebra.hpp include/arc4.hpp include/asn.hpp include/block.hpp
|
||||
include/coding.hpp include/des.hpp include/dh.hpp include/dsa.hpp include/dsa.hpp
|
||||
include/error.hpp include/file.hpp include/hash.hpp include/hmac.hpp include/integer.hpp
|
||||
|
@@ -96,7 +96,7 @@ public:
|
||||
|
||||
pointer allocate(size_type n, const void* = 0)
|
||||
{
|
||||
CheckSize(n);
|
||||
this->CheckSize(n);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
return NEW_TC T[n];
|
||||
|
65
extra/yassl/taocrypt/include/md4.hpp
Normal file
65
extra/yassl/taocrypt/include/md4.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/* md4.hpp
|
||||
*
|
||||
* Copyright (C) 2003 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* This file is part of yaSSL.
|
||||
*
|
||||
* yaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* yaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/* md4.hpp provides MD4 digest support
|
||||
* WANRING: MD4 is considered insecure, only use if you have to, e.g., yaSSL
|
||||
* libcurl supports needs this for NTLM authentication
|
||||
*/
|
||||
|
||||
#ifndef TAO_CRYPT_MD4_HPP
|
||||
#define TAO_CRYPT_MD4_HPP
|
||||
|
||||
#include "hash.hpp"
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
|
||||
// MD4 digest
|
||||
class MD4 : public HASHwithTransform {
|
||||
public:
|
||||
enum { BLOCK_SIZE = 64, DIGEST_SIZE = 16, PAD_SIZE = 56,
|
||||
TAO_BYTE_ORDER = LittleEndianOrder }; // in Bytes
|
||||
MD4() : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE)
|
||||
{ Init(); }
|
||||
ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); }
|
||||
word32 getBlockSize() const { return BLOCK_SIZE; }
|
||||
word32 getDigestSize() const { return DIGEST_SIZE; }
|
||||
word32 getPadSize() const { return PAD_SIZE; }
|
||||
|
||||
MD4(const MD4&);
|
||||
MD4& operator= (const MD4&);
|
||||
|
||||
void Init();
|
||||
void Swap(MD4&);
|
||||
private:
|
||||
void Transform();
|
||||
};
|
||||
|
||||
inline void swap(MD4& a, MD4& b)
|
||||
{
|
||||
a.Swap(b);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TAO_CRYPT_MD4_HPP
|
||||
|
@@ -28,10 +28,6 @@
|
||||
#ifndef yaSSL_NEW_HPP
|
||||
#define yaSSL_NEW_HPP
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __sun
|
||||
|
||||
|
@@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtaocrypt.la
|
||||
|
||||
libtaocrypt_la_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp \
|
||||
asn.cpp bftables.cpp blowfish.cpp coding.cpp des.cpp dh.cpp \
|
||||
dsa.cpp file.cpp hash.cpp integer.cpp md2.cpp md5.cpp misc.cpp \
|
||||
dsa.cpp file.cpp hash.cpp integer.cpp md2.cpp md4.cpp md5.cpp misc.cpp \
|
||||
random.cpp ripemd.cpp rsa.cpp sha.cpp template_instnt.cpp \
|
||||
tftables.cpp twofish.cpp
|
||||
|
||||
|
154
extra/yassl/taocrypt/src/md4.cpp
Normal file
154
extra/yassl/taocrypt/src/md4.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/* md4.cpp
|
||||
*
|
||||
* Copyright (C) 2003 Sawtooth Consulting Ltd.
|
||||
*
|
||||
* This file is part of yaSSL.
|
||||
*
|
||||
* yaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* yaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
|
||||
/* based on Wei Dai's md4.cpp from CryptoPP */
|
||||
|
||||
#include "runtime.hpp"
|
||||
#include "md4.hpp"
|
||||
#include "algorithm.hpp" // mySTL::swap
|
||||
|
||||
|
||||
|
||||
namespace TaoCrypt {
|
||||
|
||||
void MD4::Init()
|
||||
{
|
||||
digest_[0] = 0x67452301L;
|
||||
digest_[1] = 0xefcdab89L;
|
||||
digest_[2] = 0x98badcfeL;
|
||||
digest_[3] = 0x10325476L;
|
||||
|
||||
buffLen_ = 0;
|
||||
loLen_ = 0;
|
||||
hiLen_ = 0;
|
||||
}
|
||||
|
||||
|
||||
MD4::MD4(const MD4& that) : HASHwithTransform(DIGEST_SIZE / sizeof(word32),
|
||||
BLOCK_SIZE)
|
||||
{
|
||||
buffLen_ = that.buffLen_;
|
||||
loLen_ = that.loLen_;
|
||||
hiLen_ = that.hiLen_;
|
||||
|
||||
memcpy(digest_, that.digest_, DIGEST_SIZE);
|
||||
memcpy(buffer_, that.buffer_, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
MD4& MD4::operator= (const MD4& that)
|
||||
{
|
||||
MD4 tmp(that);
|
||||
Swap(tmp);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void MD4::Swap(MD4& other)
|
||||
{
|
||||
mySTL::swap(loLen_, other.loLen_);
|
||||
mySTL::swap(hiLen_, other.hiLen_);
|
||||
mySTL::swap(buffLen_, other.buffLen_);
|
||||
|
||||
memcpy(digest_, other.digest_, DIGEST_SIZE);
|
||||
memcpy(buffer_, other.buffer_, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void MD4::Transform()
|
||||
{
|
||||
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
word32 A, B, C, D;
|
||||
|
||||
A = digest_[0];
|
||||
B = digest_[1];
|
||||
C = digest_[2];
|
||||
D = digest_[3];
|
||||
|
||||
#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+buffer_[k],s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 1, 7);
|
||||
function(C,D,A,B, 2,11);
|
||||
function(B,C,D,A, 3,19);
|
||||
function(A,B,C,D, 4, 3);
|
||||
function(D,A,B,C, 5, 7);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A, 7,19);
|
||||
function(A,B,C,D, 8, 3);
|
||||
function(D,A,B,C, 9, 7);
|
||||
function(C,D,A,B,10,11);
|
||||
function(B,C,D,A,11,19);
|
||||
function(A,B,C,D,12, 3);
|
||||
function(D,A,B,C,13, 7);
|
||||
function(C,D,A,B,14,11);
|
||||
function(B,C,D,A,15,19);
|
||||
|
||||
#undef function
|
||||
#define function(a,b,c,d,k,s) a=rotlFixed(a+G(b,c,d)+buffer_[k]+0x5a827999,s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 4, 5);
|
||||
function(C,D,A,B, 8, 9);
|
||||
function(B,C,D,A,12,13);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 5, 5);
|
||||
function(C,D,A,B, 9, 9);
|
||||
function(B,C,D,A,13,13);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C, 6, 5);
|
||||
function(C,D,A,B,10, 9);
|
||||
function(B,C,D,A,14,13);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C, 7, 5);
|
||||
function(C,D,A,B,11, 9);
|
||||
function(B,C,D,A,15,13);
|
||||
|
||||
#undef function
|
||||
#define function(a,b,c,d,k,s) a=rotlFixed(a+H(b,c,d)+buffer_[k]+0x6ed9eba1,s);
|
||||
function(A,B,C,D, 0, 3);
|
||||
function(D,A,B,C, 8, 9);
|
||||
function(C,D,A,B, 4,11);
|
||||
function(B,C,D,A,12,15);
|
||||
function(A,B,C,D, 2, 3);
|
||||
function(D,A,B,C,10, 9);
|
||||
function(C,D,A,B, 6,11);
|
||||
function(B,C,D,A,14,15);
|
||||
function(A,B,C,D, 1, 3);
|
||||
function(D,A,B,C, 9, 9);
|
||||
function(C,D,A,B, 5,11);
|
||||
function(B,C,D,A,13,15);
|
||||
function(A,B,C,D, 3, 3);
|
||||
function(D,A,B,C,11, 9);
|
||||
function(C,D,A,B, 7,11);
|
||||
function(B,C,D,A,15,15);
|
||||
|
||||
digest_[0] += A;
|
||||
digest_[1] += B;
|
||||
digest_[2] += C;
|
||||
digest_[3] += D;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
@@ -30,11 +30,11 @@
|
||||
#include "sha.hpp"
|
||||
#include "md5.hpp"
|
||||
#include "hmac.hpp"
|
||||
#include "ripemd.hpp"
|
||||
#include "pwdbased.hpp"
|
||||
#include "algebra.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "hash.hpp"
|
||||
#include "ripemd.hpp"
|
||||
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
namespace TaoCrypt {
|
||||
|
@@ -146,6 +146,10 @@ SOURCE=.\src\md2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\md4.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\md5.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -246,6 +250,10 @@ SOURCE=.\include\md2.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\md4.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\include\md5.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "sha.hpp"
|
||||
#include "md5.hpp"
|
||||
#include "md2.hpp"
|
||||
#include "md4.hpp"
|
||||
#include "ripemd.hpp"
|
||||
#include "hmac.hpp"
|
||||
#include "arc4.hpp"
|
||||
@@ -30,6 +31,7 @@ using TaoCrypt::word32;
|
||||
using TaoCrypt::SHA;
|
||||
using TaoCrypt::MD5;
|
||||
using TaoCrypt::MD2;
|
||||
using TaoCrypt::MD4;
|
||||
using TaoCrypt::RIPEMD160;
|
||||
using TaoCrypt::HMAC;
|
||||
using TaoCrypt::ARC4;
|
||||
@@ -89,6 +91,7 @@ void file_test(int, char**);
|
||||
int sha_test();
|
||||
int md5_test();
|
||||
int md2_test();
|
||||
int md4_test();
|
||||
int ripemd_test();
|
||||
int hmac_test();
|
||||
int arc4_test();
|
||||
@@ -165,6 +168,11 @@ void taocrypt_test(void* args)
|
||||
else
|
||||
printf( "MD2 test passed!\n");
|
||||
|
||||
if ( (ret = md4_test()) )
|
||||
err_sys("MD4 test failed!\n", ret);
|
||||
else
|
||||
printf( "MD4 test passed!\n");
|
||||
|
||||
if ( (ret = ripemd_test()) )
|
||||
err_sys("RIPEMD test failed!\n", ret);
|
||||
else
|
||||
@@ -348,6 +356,51 @@ int md5_test()
|
||||
}
|
||||
|
||||
|
||||
int md4_test()
|
||||
{
|
||||
MD4 md4;
|
||||
byte hash[MD4::DIGEST_SIZE];
|
||||
|
||||
testVector test_md4[] =
|
||||
{
|
||||
testVector("",
|
||||
"\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89"
|
||||
"\xc0"),
|
||||
testVector("a",
|
||||
"\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb"
|
||||
"\x24"),
|
||||
testVector("abc",
|
||||
"\xa4\x48\x01\x7a\xaf\x21\xd8\x52\x5f\xc1\x0a\xe8\x7a\xa6\x72"
|
||||
"\x9d"),
|
||||
testVector("message digest",
|
||||
"\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01"
|
||||
"\x4b"),
|
||||
testVector("abcdefghijklmnopqrstuvwxyz",
|
||||
"\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd\xee\xa8\xed\x63\xdf\x41\x2d"
|
||||
"\xa9"),
|
||||
testVector("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345"
|
||||
"6789",
|
||||
"\x04\x3f\x85\x82\xf2\x41\xdb\x35\x1c\xe6\x27\xe1\x53\xe7\xf0"
|
||||
"\xe4"),
|
||||
testVector("1234567890123456789012345678901234567890123456789012345678"
|
||||
"9012345678901234567890",
|
||||
"\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f\xcc\x05"
|
||||
"\x36")
|
||||
};
|
||||
|
||||
int times( sizeof(test_md4) / sizeof(testVector) );
|
||||
for (int i = 0; i < times; ++i) {
|
||||
md4.Update(test_md4[i].input_, test_md4[i].inLen_);
|
||||
md4.Final(hash);
|
||||
|
||||
if (memcmp(hash, test_md4[i].output_, MD4::DIGEST_SIZE) != 0)
|
||||
return -5 - i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int md2_test()
|
||||
{
|
||||
MD2 md5;
|
||||
|
@@ -33,10 +33,16 @@
|
||||
|
||||
|
||||
// HPUX doesn't use socklent_t for third parameter to accept
|
||||
#if !defined(__hpux__)
|
||||
#if !defined(__hpux)
|
||||
typedef socklen_t* ACCEPT_THIRD_T;
|
||||
#else
|
||||
typedef int* ACCEPT_THIRD_T;
|
||||
|
||||
// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
|
||||
#ifndef _POSIX_THREADS
|
||||
#define _POSIX_THREADS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -240,4 +240,22 @@ extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
LEX_STRING -- a pair of a C-string and its length.
|
||||
|
||||
NOTE: this exactly form of declaration is required for some C-compilers
|
||||
(for one, Sun C 5.7 2005/01/07). Unfortunatelt with such declaration
|
||||
LEX_STRING can not be forward declared.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *str;
|
||||
uint length;
|
||||
} LEX_STRING;
|
||||
|
||||
#define STRING_WITH_LEN(X) (X), ((uint) (sizeof(X) - 1))
|
||||
#define C_STRING_WITH_SIZE(X) ((char *) (X)), ((uint) (sizeof(X) - 1))
|
||||
|
||||
#endif
|
||||
|
@@ -77,6 +77,10 @@ extern int NEAR my_errno; /* Last error in mysys */
|
||||
#define MY_GIVE_INFO 2 /* Give time info about process*/
|
||||
#define MY_DONT_FREE_DBUG 4 /* Do not call DBUG_END() in my_end() */
|
||||
|
||||
#define MY_REMOVE_NONE 0 /* Params for modify_defaults_file */
|
||||
#define MY_REMOVE_OPTION 1
|
||||
#define MY_REMOVE_SECTION 2
|
||||
|
||||
#define ME_HIGHBYTE 8 /* Shift for colours */
|
||||
#define ME_NOCUR 1 /* Don't use curses message */
|
||||
#define ME_OLDWIN 2 /* Use old window */
|
||||
|
@@ -423,17 +423,11 @@ char *octet2hex(char *to, const char *str, unsigned int len);
|
||||
|
||||
/* end of password.c */
|
||||
|
||||
char *get_tty_password(char *opt_message);
|
||||
char *get_tty_password(const char *opt_message);
|
||||
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
|
||||
|
||||
/* Some other useful functions */
|
||||
|
||||
my_bool my_init(void);
|
||||
extern int modify_defaults_file(const char *file_location, const char *option,
|
||||
const char *option_value,
|
||||
const char *section_name, int remove_option);
|
||||
int load_defaults(const char *conf_file, const char **groups,
|
||||
int *argc, char ***argv);
|
||||
my_bool my_thread_init(void);
|
||||
void my_thread_end(void);
|
||||
|
||||
|
@@ -75,7 +75,7 @@
|
||||
#define _cputs(A) putstring(A)
|
||||
#endif
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
char *get_tty_password(const char *opt_message)
|
||||
{
|
||||
char to[80];
|
||||
char *pos=to,*end=to+sizeof(to)-1;
|
||||
@@ -159,7 +159,7 @@ static void get_password(char *to,uint length,int fd,bool echo)
|
||||
#endif /* ! HAVE_GETPASS */
|
||||
|
||||
|
||||
char *get_tty_password(char *opt_message)
|
||||
char *get_tty_password(const char *opt_message)
|
||||
{
|
||||
#ifdef HAVE_GETPASS
|
||||
char *passbuff;
|
||||
|
@@ -68,7 +68,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
|
||||
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
|
||||
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
|
||||
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
|
||||
event_executor.cc event.cc event_timed.cc \
|
||||
event_scheduler.cc event.cc event_timed.cc \
|
||||
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
|
||||
sql_tablespace.cc \
|
||||
rpl_injector.cc my_user.c partition_info.cc
|
||||
|
@@ -1220,9 +1220,12 @@ sub environment_setup () {
|
||||
$ENV{'NDBCLUSTER_PORT_SLAVE'}=$opt_ndbcluster_port_slave;
|
||||
$ENV{'NDB_STATUS_OK'}= "YES";
|
||||
|
||||
$ENV{'IM_EXE'}= $exe_im;
|
||||
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
|
||||
$ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
|
||||
$ENV{'IM_PORT'}= $instance_manager->{port};
|
||||
$ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file};
|
||||
$ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file};
|
||||
|
||||
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
|
||||
$ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port};
|
||||
|
@@ -17,13 +17,13 @@ db_x
|
||||
SHOW TABLES FROM db_x;
|
||||
Tables_in_db_x
|
||||
x_table
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
DROP EVENT e_x1;
|
||||
DROP EVENT e_x2;
|
||||
DROP DATABASE db_x;
|
||||
DROP USER pauline@localhost;
|
||||
USE events_test;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
drop event if exists event1;
|
||||
Warnings:
|
||||
Note 1305 Event event1 does not exist
|
||||
@@ -100,7 +100,7 @@ a
|
||||
800219
|
||||
drop event non_qualif_ev;
|
||||
drop table non_qualif;
|
||||
set global event_scheduler = 0;
|
||||
set global event_scheduler = 2;
|
||||
create table t_event3 (a int, b float);
|
||||
drop event if exists event3;
|
||||
Warnings:
|
||||
@@ -324,18 +324,18 @@ events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
"This should show us only 3 events:";
|
||||
SHOW FULL EVENTS;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
"This should show us only 2 events:";
|
||||
SHOW FULL EVENTS LIKE 't%event';
|
||||
SHOW EVENTS LIKE 't%event';
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
"This should show us no events:";
|
||||
SHOW FULL EVENTS FROM test LIKE '%';
|
||||
SHOW EVENTS FROM test LIKE '%';
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
DROP DATABASE events_test2;
|
||||
"should see 1 event:";
|
||||
@@ -343,11 +343,8 @@ SHOW EVENTS;
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
|
||||
"we should see 4 events now:";
|
||||
SHOW FULL EVENTS;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
|
||||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from information_schema.events;
|
||||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
|
||||
@@ -373,12 +370,12 @@ ERROR HY000: Incorrect AT value: 'definitely not a datetime'
|
||||
set names utf8;
|
||||
create event задачка on schedule every 123 minute starts now() ends now() + interval 1 month do select 1;
|
||||
drop event задачка;
|
||||
set event_scheduler=0;
|
||||
set event_scheduler=2;
|
||||
ERROR HY000: Variable 'event_scheduler' is a GLOBAL variable and should be set with SET GLOBAL
|
||||
set global event_scheduler=2;
|
||||
ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2'
|
||||
set global event_scheduler=3;
|
||||
ERROR 42000: Variable 'event_scheduler' can't be set to the value of '3'
|
||||
"DISABLE the scheduler. Testing that it does not work when the variable is 0"
|
||||
set global event_scheduler=0;
|
||||
set global event_scheduler=2;
|
||||
select definer, name, db from mysql.event;
|
||||
definer name db
|
||||
select get_lock("test_lock1", 20);
|
||||
@@ -389,9 +386,10 @@ create event закачка on schedule every 10 hour do select get_lock("test_l
|
||||
select definer, name, db from mysql.event;
|
||||
definer name db
|
||||
root@localhost закачка events_test
|
||||
"Should be 0 processes"
|
||||
"Should be only 1 process"
|
||||
select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
user host db command state info
|
||||
event_scheduler localhost NULL Connect Suspended NULL
|
||||
select release_lock("test_lock1");
|
||||
release_lock("test_lock1")
|
||||
1
|
||||
@@ -409,11 +407,12 @@ get_lock("test_lock2", 20)
|
||||
create event закачка on schedule every 10 hour do select get_lock("test_lock2", 20);
|
||||
"Let some time pass to the event starts"
|
||||
"Should have only 2 processes: the scheduler and the locked event"
|
||||
select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
user host db command state info
|
||||
event_scheduler localhost NULL Connect Sleeping NULL
|
||||
root localhost events_test Connect User lock select get_lock("test_lock2", 20)
|
||||
"Release the mutex, the event worker should finish."
|
||||
"Release the mutex, the event worker should finish."
|
||||
select release_lock("test_lock2");
|
||||
release_lock("test_lock2")
|
||||
1
|
||||
@@ -423,21 +422,17 @@ select get_lock("test_lock2_1", 20);
|
||||
get_lock("test_lock2_1", 20)
|
||||
1
|
||||
create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
|
||||
"Should see 1 process, locked on get_lock("
|
||||
"Shutting down the scheduler, it should wait for the running event"
|
||||
set global event_scheduler=0;
|
||||
"Should have only 2 processes: the scheduler and the locked event"
|
||||
select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
"Should have only 3 processes: the scheduler, our conn and the locked event"
|
||||
select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
user host db command state info
|
||||
event_scheduler localhost NULL Connect Sleeping NULL
|
||||
root localhost events_test Connect User lock select get_lock("test_lock2_1", 20)
|
||||
"Release the lock so the child process should finish. Hence the scheduler also"
|
||||
select release_lock("test_lock2_1");
|
||||
release_lock("test_lock2_1")
|
||||
1
|
||||
"Should see 0 processes now:"
|
||||
select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
set global event_scheduler=2;
|
||||
"Should have only our process now:"
|
||||
select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
user host db command state info
|
||||
event_scheduler localhost NULL Connect Suspended NULL
|
||||
root localhost events_test Connect User lock select get_lock("test_lock2_1", 20)
|
||||
drop event закачка21;
|
||||
create table t_16 (s1 int);
|
||||
create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5;
|
||||
@@ -457,6 +452,9 @@ select 2;
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
event_schema event_name definer event_body
|
||||
events_test white_space root@localhost select 2
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
event_schema event_name definer event_body
|
||||
events_test white_space root@localhost select 2
|
||||
drop event white_space;
|
||||
create event white_space on schedule every 10 hour disable do select 3;
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
|
@@ -35,7 +35,7 @@ create event e_55 on schedule every 10 hour starts 99990101000000 do drop table
|
||||
ERROR HY000: Incorrect STARTS value: '99990101000000'
|
||||
create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t;
|
||||
ERROR HY000: ENDS is either invalid or before STARTS
|
||||
set global event_scheduler=0;
|
||||
set global event_scheduler=2;
|
||||
"Wait a bit to settle down"
|
||||
delete from mysql.event;
|
||||
set global event_scheduler= 1;
|
||||
@@ -57,7 +57,7 @@ root localhost events_test Connect User lock select get_lock('test_bug16407', 60
|
||||
select release_lock('test_bug16407');
|
||||
release_lock('test_bug16407')
|
||||
1
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
|
||||
event_schema event_name sql_mode
|
||||
events_test e_16407 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
|
||||
@@ -115,7 +115,7 @@ release_lock('ee_16407_2')
|
||||
select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
user host db command state info
|
||||
event_scheduler localhost NULL Connect Sleeping NULL
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
select * from events_smode_test order by ev_name, a;
|
||||
ev_name a
|
||||
ee_16407_3 1980-02-19
|
||||
@@ -175,7 +175,7 @@ drop event ee_16407_5;
|
||||
drop event ee_16407_6;
|
||||
drop procedure ee_16407_5_pendant;
|
||||
drop procedure ee_16407_6_pendant;
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
drop table events_smode_test;
|
||||
set sql_mode=@old_sql_mode;
|
||||
drop database events_test;
|
||||
|
@@ -8,7 +8,7 @@ BEGIN
|
||||
SELECT user_host, argument FROM mysql.general_log WHERE argument LIKE '%alabala%';
|
||||
END|
|
||||
"Check General Query Log"
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
create event log_general on schedule every 1 minute do SELect 'alabala', sleep(3) from dual;
|
||||
TRUNCATE mysql.general_log;
|
||||
"1 row, the current statement!"
|
||||
@@ -22,7 +22,7 @@ user_host argument
|
||||
root[root] @ localhost [localhost] SELect 'alabala', sleep(3) from dual
|
||||
DROP PROCEDURE select_general_log;
|
||||
DROP EVENT log_general;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
"Check slow query log"
|
||||
"Save the values"
|
||||
SET @old_global_long_query_time:=(select get_value());
|
||||
@@ -36,14 +36,14 @@ SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
"Set new values"
|
||||
SET GLOBAL long_query_time=4;
|
||||
SET SESSION long_query_time=2;
|
||||
SET SESSION long_query_time=1;
|
||||
"Check that logging is working"
|
||||
SELECT SLEEP(3);
|
||||
SLEEP(3)
|
||||
SELECT SLEEP(2);
|
||||
SLEEP(2)
|
||||
0
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
root[root] @ localhost [] SLEEPVAL events_test SELECT SLEEP(3)
|
||||
root[root] @ localhost [] SLEEPVAL events_test SELECT SLEEP(2)
|
||||
TRUNCATE mysql.slow_log;
|
||||
CREATE TABLE slow_event_test (slo_val tinyint, val tinyint);
|
||||
"This won't go to the slow log"
|
||||
@@ -54,7 +54,7 @@ SET GLOBAL event_scheduler=1;
|
||||
"Sleep some more time than the actual event run will take"
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler ON
|
||||
event_scheduler 1
|
||||
"Check our table. Should see 1 row"
|
||||
SELECT * FROM slow_event_test;
|
||||
slo_val val
|
||||
@@ -64,18 +64,19 @@ SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
"This should go to the slow log"
|
||||
SET SESSION long_query_time=10;
|
||||
SET GLOBAL long_query_time=1;
|
||||
DROP EVENT long_event;
|
||||
CREATE EVENT long_event2 ON SCHEDULE EVERY 1 MINUTE DO INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(5);
|
||||
CREATE EVENT long_event2 ON SCHEDULE EVERY 1 MINUTE DO INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(2);
|
||||
"Sleep some more time than the actual event run will take"
|
||||
"Check our table. Should see 2 rows"
|
||||
SELECT * FROM slow_event_test;
|
||||
slo_val val
|
||||
4 0
|
||||
4 0
|
||||
"Check slow log. Should see 1 row because 5 is over the threshold of 4 for GLOBAL, though under SESSION which is 10"
|
||||
1 0
|
||||
"Check slow log. Should see 1 row because 4 is over the threshold of 3 for GLOBAL, though under SESSION which is 10"
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
user_host query_time db sql_text
|
||||
root[root] @ localhost [localhost] SLEEPVAL events_test INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(5)
|
||||
root[root] @ localhost [localhost] SLEEPVAL events_test INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(2)
|
||||
DROP EVENT long_event2;
|
||||
SET GLOBAL long_query_time =@old_global_long_query_time;
|
||||
SET SESSION long_query_time =@old_session_long_query_time;
|
||||
|
@@ -10,50 +10,4 @@ CREATE EVENT micro_test ON SCHEDULE EVERY 100 MINUTE_MICROSECOND DO SELECT 1;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 SECOND_MICROSECOND DO SELECT 1;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
"Now create normal event and change it on SQL level"
|
||||
CREATE EVENT micro_test2 ON SCHEDULE EVERY 1 MONTH DO SELECT 1;
|
||||
UPDATE mysql.event SET interval_field='MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
SET GLOBAL event_scheduler=0;
|
||||
"Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
UPDATE mysql.event SET interval_field='DAY_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
SET GLOBAL event_scheduler=0;
|
||||
"Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
UPDATE mysql.event SET interval_field='SECOND_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
SET GLOBAL event_scheduler=0;
|
||||
"Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
UPDATE mysql.event SET interval_field='HOUR_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
SET GLOBAL event_scheduler=0;
|
||||
"Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
UPDATE mysql.event SET interval_field='MINUTE_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
|
||||
SET GLOBAL event_scheduler=0;
|
||||
"Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER='event_scheduler';
|
||||
COUNT(*)
|
||||
0
|
||||
DROP EVENT micro_test2;
|
||||
drop database events_test;
|
||||
|
@@ -14,7 +14,7 @@ ENDS NOW() + INTERVAL 6 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO INSERT INTO table_2 VALUES(1);
|
||||
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND ON COMPLETION PRESERVE DO INSERT INTO table_4 VALUES(1);
|
||||
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
|
||||
IF(SUM(a) >= 4, 'OK', 'ERROR')
|
||||
OK
|
||||
@@ -38,9 +38,12 @@ DROP EVENT start_n_end;
|
||||
"Already dropped because ended. Therefore an error."
|
||||
DROP EVENT only_one_time;
|
||||
ERROR HY000: Unknown event 'only_one_time'
|
||||
"Already dropped because ended. Therefore an error."
|
||||
"Should be preserved"
|
||||
SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS;
|
||||
EVENT_NAME STATUS
|
||||
E19170 ENABLED
|
||||
two_time DISABLED
|
||||
DROP EVENT two_time;
|
||||
ERROR HY000: Unknown event 'two_time'
|
||||
DROP TABLE table_1;
|
||||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
|
@@ -1,46 +1,61 @@
|
||||
CREATE DATABASE IF NOT EXISTS events_test;
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
CREATE TABLE events_test.fill_it(test_name varchar(20), occur datetime);
|
||||
CREATE USER event_user2@localhost;
|
||||
CREATE DATABASE events_conn2_db;
|
||||
GRANT ALL ON *.* TO event_user2@localhost;
|
||||
CREATE USER event_user3@localhost;
|
||||
CREATE DATABASE events_conn3_db;
|
||||
GRANT ALL ON *.* TO event_user3@localhost;
|
||||
"In the second connection we create some events which won't be dropped till the end"
|
||||
"In the second connection we create some events which won't be dropped till the end"
|
||||
USE events_conn1_test2;
|
||||
CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
USE events_test;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS;
|
||||
COUNT(*)
|
||||
103
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
COUNT(*)
|
||||
3
|
||||
DROP DATABASE events_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
DROP DATABASE events_conn1_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
COUNT(*)
|
||||
0
|
||||
"Now testing stability - dropping db -> events while they are running"
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
USE events_conn1_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
COUNT(*)
|
||||
1000
|
||||
50
|
||||
SET GLOBAL event_scheduler=1;
|
||||
DROP DATABASE events_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
DROP DATABASE events_conn1_test2;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
COUNT(*)
|
||||
0
|
||||
CREATE DATABASE events_test3;
|
||||
USE events_test3;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test3';
|
||||
COUNT(*)
|
||||
950
|
||||
CREATE DATABASE events_test4;
|
||||
USE events_test4;
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
COUNT(*)
|
||||
1050
|
||||
DROP DATABASE events_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
DROP DATABASE events_test3;
|
||||
CREATE DATABASE events_conn1_test3;
|
||||
USE events_conn1_test3;
|
||||
SET GLOBAL event_scheduler=1;
|
||||
DROP DATABASE events_test4;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test3';
|
||||
COUNT(*)
|
||||
50
|
||||
CREATE DATABASE events_conn1_test4;
|
||||
USE events_conn1_test4;
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
USE events_conn1_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
COUNT(*)
|
||||
50
|
||||
DROP DATABASE events_conn2_db;
|
||||
DROP DATABASE events_conn3_db;
|
||||
DROP DATABASE events_conn1_test2;
|
||||
DROP DATABASE events_conn1_test3;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
DROP DATABASE events_conn1_test4;
|
||||
SET GLOBAL event_scheduler=1;
|
||||
USE events_test;
|
||||
DROP TABLE fill_it;
|
||||
DROP DATABASE events_test;
|
||||
|
40
mysql-test/r/im_cmd_line.result
Normal file
40
mysql-test/r/im_cmd_line.result
Normal file
@@ -0,0 +1,40 @@
|
||||
--> Listing users...
|
||||
im_admin
|
||||
|
||||
==> Adding user 'testuser'...
|
||||
|
||||
--> IM password file:
|
||||
testuser:*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
|
||||
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
|
||||
--> EOF
|
||||
|
||||
--> Printing out line for 'testuser'...
|
||||
testuser:*0D3CED9BEC10A777AEC23CCC353A8C08A633045E
|
||||
|
||||
--> Listing users...
|
||||
im_admin
|
||||
testuser
|
||||
|
||||
==> Changing the password of 'testuser'...
|
||||
|
||||
--> IM password file:
|
||||
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
|
||||
testuser:*39C549BDECFBA8AFC3CE6B948C9359A0ECE08DE2
|
||||
--> EOF
|
||||
|
||||
--> Printing out line for 'testuser'...
|
||||
testuser:*39C549BDECFBA8AFC3CE6B948C9359A0ECE08DE2
|
||||
|
||||
--> Listing users...
|
||||
testuser
|
||||
im_admin
|
||||
|
||||
==> Dropping user 'testuser'...
|
||||
|
||||
--> IM password file:
|
||||
im_admin:*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295
|
||||
--> EOF
|
||||
|
||||
--> Listing users...
|
||||
im_admin
|
||||
|
@@ -1,5 +1,5 @@
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
Killing the process...
|
||||
|
196
mysql-test/r/im_instance_conf.result
Normal file
196
mysql-test/r/im_instance_conf.result
Normal file
@@ -0,0 +1,196 @@
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
|
||||
---> connection: mysql1_con
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
|
||||
---> connection: default
|
||||
CREATE INSTANCE mysqld3;
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld3 offline
|
||||
mysqld2 offline
|
||||
mysqld1 online
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld1;
|
||||
ERROR HY000: Instance already exists
|
||||
CREATE INSTANCE mysqld2;
|
||||
ERROR HY000: Instance already exists
|
||||
CREATE INSTANCE mysqld3;
|
||||
ERROR HY000: Instance already exists
|
||||
--------------------------------------------------------------------
|
||||
nonguarded
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld4 nonguarded;
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
--------------------------------------------------------------------
|
||||
nonguarded
|
||||
nonguarded
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld5 test-A = 000, test-B = test;
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld4 offline
|
||||
mysqld5 offline
|
||||
mysqld2 offline
|
||||
mysqld3 offline
|
||||
--------------------------------------------------------------------
|
||||
test-A=000
|
||||
--------------------------------------------------------------------
|
||||
test-B=test
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld6 test-C1 = 10 , test-C2 = 02 ;
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
--------------------------------------------------------------------
|
||||
test-C1=10
|
||||
--------------------------------------------------------------------
|
||||
test-C2=02
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld7 test-D = test-D-value ;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
CREATE INSTANCE mysqld8 test-E 0 ;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
CREATE INSTANCE mysqld8 test-F = ;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE mysqld9 test-1=" hello world ", test-2=' ';
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld9 offline
|
||||
CREATE INSTANCE mysqld9a test-3='\b\babc\sdef';
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld9a offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld9 offline
|
||||
mysqld2 offline
|
||||
CREATE INSTANCE mysqld9b test-4='abc\tdef', test-5='abc\ndef';
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld9b offline
|
||||
mysqld9a offline
|
||||
mysqld5 offline
|
||||
mysqld6 offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld9 offline
|
||||
mysqld2 offline
|
||||
mysqld1 online
|
||||
CREATE INSTANCE mysqld9c test-6="abc\rdef", test-7="abc\\def";
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld9b offline
|
||||
mysqld6 offline
|
||||
mysqld5 offline
|
||||
mysqld9c offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld9 offline
|
||||
mysqld2 offline
|
||||
mysqld1 online
|
||||
mysqld9a offline
|
||||
CREATE INSTANCE mysqld10 test-bad=' \ ';
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld9b offline
|
||||
mysqld6 offline
|
||||
mysqld5 offline
|
||||
mysqld9c offline
|
||||
mysqld3 offline
|
||||
mysqld4 offline
|
||||
mysqld9 offline
|
||||
mysqld2 offline
|
||||
mysqld1 online
|
||||
mysqld9a offline
|
||||
--------------------------------------------------------------------
|
||||
test-1= hello world
|
||||
--------------------------------------------------------------------
|
||||
test-2=
|
||||
--------------------------------------------------------------------
|
||||
test-3=abc def
|
||||
--------------------------------------------------------------------
|
||||
test-4=abc def
|
||||
--------------------------------------------------------------------
|
||||
test-5=abc
|
||||
--------------------------------------------------------------------
|
||||
test-6=abc
|
||||
def
|
||||
--------------------------------------------------------------------
|
||||
test-7=abc\def
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
CREATE INSTANCE qqq1;
|
@@ -1,69 +1,93 @@
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.1.
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
instance_name status version_number version
|
||||
mysqld1 online VERSION_NUMBER VERSION
|
||||
SHOW INSTANCE STATUS mysqld2;
|
||||
instance_name status version_number version
|
||||
mysqld2 offline VERSION_NUMBER VERSION
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.2.
|
||||
--------------------------------------------------------------------
|
||||
START INSTANCE mysqld2;
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 online
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
instance_name status version_number version
|
||||
mysqld1 online VERSION_NUMBER VERSION
|
||||
SHOW INSTANCE STATUS mysqld2;
|
||||
instance_name status version_number version
|
||||
mysqld2 online VERSION_NUMBER VERSION
|
||||
SHOW VARIABLES LIKE 'port';
|
||||
Variable_name Value
|
||||
port IM_MYSQLD1_PORT
|
||||
port IM_MYSQLD2_PORT
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.3.
|
||||
--------------------------------------------------------------------
|
||||
STOP INSTANCE mysqld2;
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
instance_name status version_number version
|
||||
mysqld1 online VERSION_NUMBER VERSION
|
||||
instance_name state version_number version mysqld_compatible
|
||||
mysqld1 online VERSION_NUMBER VERSION no
|
||||
SHOW INSTANCE STATUS mysqld2;
|
||||
instance_name status version_number version
|
||||
mysqld2 offline VERSION_NUMBER VERSION
|
||||
instance_name state version_number version mysqld_compatible
|
||||
mysqld2 offline VERSION_NUMBER VERSION no
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.4.
|
||||
--------------------------------------------------------------------
|
||||
START INSTANCE mysqld3;
|
||||
ERROR HY000: Bad instance name. Check that the instance with such a name exists
|
||||
START INSTANCE mysqld1;
|
||||
ERROR HY000: The instance is already started
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.5.
|
||||
--------------------------------------------------------------------
|
||||
STOP INSTANCE mysqld3;
|
||||
ERROR HY000: Bad instance name. Check that the instance with such a name exists
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.6.
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
Killing the process...
|
||||
Sleeping...
|
||||
Success: the process was restarted.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.7.
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
START INSTANCE mysqld2;
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 online
|
||||
Killing the process...
|
||||
Sleeping...
|
||||
Success: the process was killed.
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 1.1.8.
|
||||
--------------------------------------------------------------------
|
||||
SHOW INSTANCE STATUS;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- BUG#12813
|
||||
--------------------------------------------------------------------
|
||||
START INSTANCE mysqld1,mysqld2,mysqld3;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
STOP INSTANCE mysqld1,mysqld2,mysqld3;
|
||||
|
150
mysql-test/r/im_options.result
Normal file
150
mysql-test/r/im_options.result
Normal file
@@ -0,0 +1,150 @@
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
--------------------------------------------------------------------
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 starting
|
||||
mysqld2 offline
|
||||
UNSET mysqld1.server_id;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
SET mysqld1.server_id = 11;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
CREATE INSTANCE mysqld3 datadir = '/';
|
||||
START INSTANCE mysqld3;
|
||||
UNSET mysqld3.server_id;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
SET mysqld3.server_id = 11;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
STOP INSTANCE mysqld3;
|
||||
SHOW INSTANCE STATUS mysqld3;
|
||||
instance_name state version_number version mysqld_compatible
|
||||
mysqld3 offline VERSION_NUMBER VERSION no
|
||||
UNSET mysqld2.server_id;
|
||||
UNSET mysqld2.server_id;
|
||||
SHOW INSTANCE OPTIONS mysqld2;
|
||||
option_name value
|
||||
instance_name option_value
|
||||
socket option_value
|
||||
pid-file option_value
|
||||
port option_value
|
||||
datadir option_value
|
||||
log option_value
|
||||
log-error option_value
|
||||
log-slow-queries option_value
|
||||
language option_value
|
||||
character-sets-dir option_value
|
||||
basedir option_value
|
||||
skip-stack-trace option_value
|
||||
skip-innodb option_value
|
||||
skip-bdb option_value
|
||||
skip-ndbcluster option_value
|
||||
nonguarded option_value
|
||||
log-output option_value
|
||||
SET mysqld2.server_id = 2;
|
||||
SET mysqld2.server_id = 2;
|
||||
SHOW INSTANCE OPTIONS mysqld2;
|
||||
option_name value
|
||||
instance_name option_value
|
||||
socket option_value
|
||||
pid-file option_value
|
||||
port option_value
|
||||
datadir option_value
|
||||
log option_value
|
||||
log-error option_value
|
||||
log-slow-queries option_value
|
||||
language option_value
|
||||
character-sets-dir option_value
|
||||
basedir option_value
|
||||
skip-stack-trace option_value
|
||||
skip-innodb option_value
|
||||
skip-bdb option_value
|
||||
skip-ndbcluster option_value
|
||||
nonguarded option_value
|
||||
log-output option_value
|
||||
server_id option_value
|
||||
UNSET mysqld2.server_id = 11;
|
||||
ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc = 0010, mysqld3.ddd = 0020;
|
||||
--------------------------------------------------------------------
|
||||
aaa
|
||||
--------------------------------------------------------------------
|
||||
bbb
|
||||
--------------------------------------------------------------------
|
||||
ccc=0010
|
||||
--------------------------------------------------------------------
|
||||
ddd=0020
|
||||
--------------------------------------------------------------------
|
||||
UNSET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc, mysqld3.ddd;
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld.ccc = 0010;
|
||||
ERROR HY000: Bad instance name. Check that the instance with such a name exists
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld1.ccc = 0010;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
UNSET mysqld2.server_id, mysqld3.server_id, mysqld.ccc;
|
||||
ERROR HY000: Bad instance name. Check that the instance with such a name exists
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id=2
|
||||
--------------------------------------------------------------------
|
||||
UNSET mysqld2.server_id, mysqld3.server_id, mysqld1.ccc;
|
||||
ERROR HY000: The instance is active. Stop the instance first
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id=2
|
||||
--------------------------------------------------------------------
|
||||
DROP INSTANCE mysqld3;
|
||||
SET mysqld2.server_id=222;
|
||||
SET mysqld2.server_id = 222;
|
||||
SET mysqld2.server_id = 222 ;
|
||||
SET mysqld2 . server_id = 222 ;
|
||||
SET mysqld2 . server_id = 222 , mysqld2 . aaa , mysqld2 . bbb ;
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id=222
|
||||
--------------------------------------------------------------------
|
||||
aaa
|
||||
--------------------------------------------------------------------
|
||||
bbb
|
||||
--------------------------------------------------------------------
|
||||
UNSET mysqld2 . aaa , mysqld2 . bbb ;
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id=222
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
--------------------------------------------------------------------
|
||||
server_id = 1
|
||||
server_id=222
|
||||
--------------------------------------------------------------------
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
FLUSH INSTANCES;
|
||||
ERROR HY000: At least one instance is active. Stop all instances first
|
||||
STOP INSTANCE mysqld1;
|
||||
SHOW INSTANCES;
|
||||
instance_name state
|
||||
mysqld1 offline
|
||||
mysqld2 offline
|
||||
FLUSH INSTANCES;
|
@@ -1,20 +0,0 @@
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SET mysqld1.server_id = 11;
|
||||
server_id =11
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
SET mysqld2.server_id = 12;
|
||||
server_id =11
|
||||
server_id =12
|
||||
FLUSH INSTANCES;
|
||||
server_id =11
|
||||
server_id =12
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
@@ -1,15 +0,0 @@
|
||||
server_id = 1
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
UNSET mysqld1.server_id;
|
||||
server_id = 2
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
||||
UNSET mysqld2.server_id;
|
||||
FLUSH INSTANCES;
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
Variable_name Value
|
||||
server_id 1
|
@@ -1,11 +1,10 @@
|
||||
SHOW INSTANCES;
|
||||
instance_name status
|
||||
instance_name state
|
||||
mysqld1 online
|
||||
mysqld2 offline
|
||||
SHOW INSTANCE OPTIONS mysqld1;
|
||||
option_name value
|
||||
instance_name VALUE
|
||||
mysqld-path VALUE
|
||||
socket VALUE
|
||||
pid-file VALUE
|
||||
port VALUE
|
||||
@@ -25,8 +24,6 @@ log-output VALUE
|
||||
SHOW INSTANCE OPTIONS mysqld2;
|
||||
option_name value
|
||||
instance_name VALUE
|
||||
mysqld-path VALUE
|
||||
nonguarded VALUE
|
||||
socket VALUE
|
||||
pid-file VALUE
|
||||
port VALUE
|
||||
@@ -42,6 +39,7 @@ skip-stack-trace VALUE
|
||||
skip-innodb VALUE
|
||||
skip-bdb VALUE
|
||||
skip-ndbcluster VALUE
|
||||
nonguarded VALUE
|
||||
log-output VALUE
|
||||
START INSTANCE mysqld2;
|
||||
STOP INSTANCE mysqld2;
|
||||
|
@@ -2,14 +2,14 @@ use mysql;
|
||||
truncate table general_log;
|
||||
select * from general_log;
|
||||
event_time user_host thread_id server_id command_type argument
|
||||
TIMESTAMP root[root] @ localhost [] 1 1 Query select * from general_log
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query select * from general_log
|
||||
truncate table slow_log;
|
||||
select * from slow_log;
|
||||
start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text
|
||||
truncate table general_log;
|
||||
select * from general_log where argument like '%general_log%';
|
||||
event_time user_host thread_id server_id command_type argument
|
||||
TIMESTAMP root[root] @ localhost [] 1 1 Query select * from general_log where argument like '%general_log%'
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query select * from general_log where argument like '%general_log%'
|
||||
create table join_test (verbose_comment varchar (80), command_type varchar(64));
|
||||
insert into join_test values ("User performed a usual SQL query", "Query");
|
||||
insert into join_test values ("New DB connection was registered", "Connect");
|
||||
@@ -59,10 +59,10 @@ create table bug16905 (s char(15) character set utf8 default 'пусто');
|
||||
insert into bug16905 values ('новое');
|
||||
select * from mysql.general_log;
|
||||
event_time user_host thread_id server_id command_type argument
|
||||
TIMESTAMP root[root] @ localhost [] 2 1 Query set names utf8
|
||||
TIMESTAMP root[root] @ localhost [] 2 1 Query create table bug16905 (s char(15) character set utf8 default 'пусто')
|
||||
TIMESTAMP root[root] @ localhost [] 2 1 Query insert into bug16905 values ('новое')
|
||||
TIMESTAMP root[root] @ localhost [] 2 1 Query select * from mysql.general_log
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query set names utf8
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query create table bug16905 (s char(15) character set utf8 default 'пусто')
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query insert into bug16905 values ('новое')
|
||||
TIMESTAMP root[root] @ localhost [] THREAD_ID 1 Query select * from mysql.general_log
|
||||
drop table bug16905;
|
||||
truncate table mysql.slow_log;
|
||||
set session long_query_time=1;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
prepare stmt1 from ' show full processlist ';
|
||||
execute stmt1;
|
||||
Id User Host db Command Time State Info
|
||||
number event_scheduler localhost NULL Connect time Suspended NULL
|
||||
number root localhost test Query time NULL show full processlist
|
||||
deallocate prepare stmt1;
|
||||
|
@@ -299,7 +299,7 @@ t9 MyISAM 10 Dynamic 2 216 432 # 2048 0 NULL # # # latin1_swedish_ci NULL
|
||||
prepare stmt4 from ' show status like ''Threads_running'' ';
|
||||
execute stmt4;
|
||||
Variable_name Value
|
||||
Threads_running 1
|
||||
Threads_running 2
|
||||
prepare stmt4 from ' show variables like ''sql_mode'' ';
|
||||
execute stmt4;
|
||||
Variable_name Value
|
||||
|
@@ -10,5 +10,6 @@ user()
|
||||
#
|
||||
show processlist;
|
||||
Id User Host db Command Time State Info
|
||||
<id> event_scheduler <host> NULL <command> <time> <state> <info>
|
||||
<id> root <host> test <command> <time> <state> <info>
|
||||
<id> root <host> test <command> <time> <state> <info>
|
||||
|
@@ -34,6 +34,7 @@ lock tables t2 write;
|
||||
call bug9486();
|
||||
show processlist;
|
||||
Id User Host db Command Time State Info
|
||||
# event_scheduler localhost NULL Connect # Suspended NULL
|
||||
# root localhost test Sleep # NULL
|
||||
# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
|
||||
# root localhost test Query # NULL show processlist
|
||||
|
@@ -18,9 +18,11 @@ show processlist;
|
||||
end|
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# event_scheduler localhost NULL Connect # Suspended NULL
|
||||
# root localhost test Query # NULL show processlist
|
||||
call bug4902_2()|
|
||||
Id User Host db Command Time State Info
|
||||
# event_scheduler localhost NULL Connect # Suspended NULL
|
||||
# root localhost test Query # NULL show processlist
|
||||
drop procedure bug4902_2|
|
||||
drop function if exists bug5278|
|
||||
|
@@ -26,20 +26,20 @@ Last_query_cost 0.000000
|
||||
FLUSH STATUS;
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 1
|
||||
Max_used_connections 2
|
||||
SET @save_thread_cache_size=@@thread_cache_size;
|
||||
SET GLOBAL thread_cache_size=3;
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 3
|
||||
Max_used_connections 4
|
||||
FLUSH STATUS;
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 2
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 3
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 4
|
||||
SHOW STATUS LIKE 'max_used_connections';
|
||||
Variable_name Value
|
||||
Max_used_connections 5
|
||||
SET GLOBAL thread_cache_size=@save_thread_cache_size;
|
||||
|
@@ -9,11 +9,10 @@
|
||||
# Do not use any TAB characters for whitespace.
|
||||
#
|
||||
##############################################################################
|
||||
events_bugs : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events_stress : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events : BUG#17619 2006-02-21 andrey Race conditions
|
||||
events_scheduling : BUG#19170 2006-04-26 andrey Test case of 19170 fails on some platforms. Has to be checked.
|
||||
events_logs_tests : BUG#17619 2006-05-16 andrey Test case problems
|
||||
#events_bugs : BUG#17619 2006-02-21 andrey Race conditions
|
||||
#events_stress : BUG#17619 2006-02-21 andrey Race conditions
|
||||
#events : BUG#17619 2006-02-21 andrey Race conditions
|
||||
#events_scheduling : BUG#19170 2006-04-26 andrey Test case of 19170 fails on some platforms. Has to be checked.
|
||||
ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
|
||||
ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog
|
||||
#ndb_binlog_discover : BUG#19395 2006-04-28 tomas/knielsen mysqld does not always detect cluster shutdown
|
||||
|
@@ -15,11 +15,10 @@ CREATE EVENT e_x2 ON SCHEDULE EVERY 1 SECOND DO DROP TABLE x_table;
|
||||
connection default;
|
||||
SHOW DATABASES LIKE 'db_x';
|
||||
SET GLOBAL event_scheduler=1;
|
||||
--sleep 2
|
||||
--sleep 1.5
|
||||
SHOW DATABASES LIKE 'db_x';
|
||||
SHOW TABLES FROM db_x;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
SET GLOBAL event_scheduler=2;
|
||||
connection priv_conn;
|
||||
DROP EVENT e_x1;
|
||||
DROP EVENT e_x2;
|
||||
@@ -31,8 +30,7 @@ USE events_test;
|
||||
#
|
||||
# END: BUG #17289 Events: missing privilege check for drop database
|
||||
#
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
SET GLOBAL event_scheduler=2;
|
||||
drop event if exists event1;
|
||||
create event event1 on schedule every 15 minute starts now() ends date_add(now(), interval 5 hour) DO begin end;
|
||||
alter event event1 rename to event2 enable;
|
||||
@@ -92,11 +90,11 @@ drop event e_43;
|
||||
--echo "Let's check whether we can use non-qualified names"
|
||||
create table non_qualif(a int);
|
||||
create event non_qualif_ev on schedule every 10 minute do insert into non_qualif values (800219);
|
||||
--sleep 2
|
||||
--sleep 1
|
||||
select * from non_qualif;
|
||||
drop event non_qualif_ev;
|
||||
drop table non_qualif;
|
||||
set global event_scheduler = 0;
|
||||
set global event_scheduler = 2;
|
||||
|
||||
create table t_event3 (a int, b float);
|
||||
drop event if exists event3;
|
||||
@@ -281,15 +279,15 @@ SHOW EVENTS;
|
||||
|
||||
--echo "This should show us only 3 events:";
|
||||
--replace_column 8 # 9 #
|
||||
SHOW FULL EVENTS;
|
||||
SHOW EVENTS;
|
||||
|
||||
--echo "This should show us only 2 events:";
|
||||
--replace_column 8 # 9 #
|
||||
SHOW FULL EVENTS LIKE 't%event';
|
||||
SHOW EVENTS LIKE 't%event';
|
||||
|
||||
--echo "This should show us no events:";
|
||||
--replace_column 8 # 9 #
|
||||
SHOW FULL EVENTS FROM test LIKE '%';
|
||||
SHOW EVENTS FROM test LIKE '%';
|
||||
#ok, we are back
|
||||
connection default;
|
||||
DROP DATABASE events_test2;
|
||||
@@ -300,7 +298,7 @@ SHOW EVENTS;
|
||||
|
||||
--echo "we should see 4 events now:";
|
||||
--replace_column 8 # 9 #
|
||||
SHOW FULL EVENTS;
|
||||
SHOW EVENTS;
|
||||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from information_schema.events;
|
||||
|
||||
connection ev_con1;
|
||||
@@ -330,21 +328,21 @@ create event задачка on schedule every 123 minute starts now() ends now()
|
||||
drop event задачка;
|
||||
|
||||
# event_scheduler is a global var
|
||||
--error 1229
|
||||
set event_scheduler=0;
|
||||
# event_scheduler could be only either 0 or 1
|
||||
--error 1231
|
||||
set global event_scheduler=2;
|
||||
--error ER_GLOBAL_VARIABLE
|
||||
set event_scheduler=2;
|
||||
# event_scheduler could be only either 1 or 2
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
set global event_scheduler=3;
|
||||
|
||||
--echo "DISABLE the scheduler. Testing that it does not work when the variable is 0"
|
||||
set global event_scheduler=0;
|
||||
set global event_scheduler=2;
|
||||
select definer, name, db from mysql.event;
|
||||
select get_lock("test_lock1", 20);
|
||||
create event закачка on schedule every 10 hour do select get_lock("test_lock1", 20);
|
||||
--echo "Should return 1 row"
|
||||
select definer, name, db from mysql.event;
|
||||
|
||||
--echo "Should be 0 processes"
|
||||
--echo "Should be only 1 process"
|
||||
select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select release_lock("test_lock1");
|
||||
drop event закачка;
|
||||
@@ -362,7 +360,7 @@ create event закачка on schedule every 10 hour do select get_lock("test_l
|
||||
--echo "Let some time pass to the event starts"
|
||||
--sleep 2
|
||||
--echo "Should have only 2 processes: the scheduler and the locked event"
|
||||
select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;--echo "Release the mutex, the event worker should finish."
|
||||
--echo "Release the mutex, the event worker should finish."
|
||||
select release_lock("test_lock2");
|
||||
drop event закачка;
|
||||
@@ -379,18 +377,11 @@ set global event_scheduler=1;
|
||||
select get_lock("test_lock2_1", 20);
|
||||
create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
|
||||
--sleep 1
|
||||
--echo "Should see 1 process, locked on get_lock("
|
||||
#select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
--echo "Shutting down the scheduler, it should wait for the running event"
|
||||
set global event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should have only 2 processes: the scheduler and the locked event"
|
||||
--echo "Should have only 3 processes: the scheduler, our conn and the locked event"
|
||||
select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
set global event_scheduler=2;
|
||||
--echo "Should have only our process now:"
|
||||
select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
--echo "Release the lock so the child process should finish. Hence the scheduler also"
|
||||
select release_lock("test_lock2_1");
|
||||
--sleep 1
|
||||
--echo "Should see 0 processes now:"
|
||||
select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
drop event закачка21;
|
||||
|
||||
####
|
||||
@@ -418,6 +409,7 @@ create event white_space on schedule every 10 hour disable do
|
||||
|
||||
select 2;
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
drop event white_space;
|
||||
create event white_space on schedule every 10 hour disable do select 3;
|
||||
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
|
||||
@@ -426,7 +418,7 @@ drop event white_space;
|
||||
# END: BUG #17453: Creating Event crash the server
|
||||
#
|
||||
|
||||
##set global event_scheduler=1;
|
||||
#
|
||||
# Bug#17403 "Events: packets out of order with show create event"
|
||||
#
|
||||
create event e1 on schedule every 1 year do set @a = 5;
|
||||
@@ -440,7 +432,7 @@ drop event e1;
|
||||
##select get_lock("test_lock3", 20);
|
||||
##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20);
|
||||
##select sleep(2);
|
||||
##show processlist;
|
||||
##select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
##drop event закачка;
|
||||
##select release_lock("test_lock3");
|
||||
|
||||
@@ -450,14 +442,14 @@ drop event e1;
|
||||
##select get_lock("test_lock4", 20);
|
||||
##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20);
|
||||
##select sleep(3);
|
||||
##--replace_column 1 # 6 #
|
||||
##select /*6*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
##drop event закачка4;
|
||||
##select release_lock("test_lock4");
|
||||
|
||||
##set global event_scheduler=0;
|
||||
##set global event_scheduler=2;
|
||||
##select sleep(2);
|
||||
##--replace_column 1 # 6 #
|
||||
##show processlist;
|
||||
##select count(*) from mysql.event;
|
||||
|
||||
drop database events_test;
|
||||
|
||||
|
@@ -30,13 +30,13 @@ set @a=3;
|
||||
CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5;
|
||||
call p_16();
|
||||
--echo "Here we used to crash!"
|
||||
--error 1516
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
call p_16();
|
||||
--error 1516
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
call p_16();
|
||||
DROP EVENT e_16;
|
||||
CALL p_16();
|
||||
--error 1516
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
CALL p_16();
|
||||
DROP PROCEDURE p_16;
|
||||
DROP EVENT e_16;
|
||||
@@ -47,9 +47,9 @@ DROP EVENT e_16;
|
||||
#
|
||||
# Start - 16396: Events: Distant-future dates become past dates
|
||||
#
|
||||
--error 1504
|
||||
--error ER_WRONG_VALUE
|
||||
create event e_55 on schedule at 99990101000000 do drop table t;
|
||||
--error 1504
|
||||
--error ER_WRONG_VALUE
|
||||
create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t;
|
||||
--error ER_EVENT_ENDS_BEFORE_STARTS
|
||||
create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t;
|
||||
@@ -60,7 +60,7 @@ create event e_55 on schedule every 10 minute ends 99990101000000 do drop table
|
||||
#
|
||||
# Start - 16407: Events: Changes in sql_mode won't be taken into account
|
||||
#
|
||||
set global event_scheduler=0;
|
||||
set global event_scheduler=2;
|
||||
--echo "Wait a bit to settle down"
|
||||
--sleep 1
|
||||
delete from mysql.event;
|
||||
@@ -79,7 +79,7 @@ delimiter ;|
|
||||
--echo "Now if everything is fine the event has compiled and is locked
|
||||
select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select release_lock('test_bug16407');
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
|
||||
--echo "Let's check whether we change the sql_mode on ALTER EVENT"
|
||||
set sql_mode='traditional';
|
||||
@@ -121,9 +121,9 @@ set global event_scheduler= 1;
|
||||
--sleep 1
|
||||
select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select release_lock('ee_16407_2');
|
||||
--sleep 3
|
||||
--sleep 2
|
||||
select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
select * from events_smode_test order by ev_name, a;
|
||||
--echo "OK, last check before we drop them"
|
||||
select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
|
||||
@@ -156,7 +156,7 @@ set global event_scheduler= 1;
|
||||
--echo "Should have 2 locked processes"
|
||||
select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select release_lock('ee_16407_5');
|
||||
--sleep 3
|
||||
--sleep 2
|
||||
--echo "Should have 0 processes locked"
|
||||
select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;
|
||||
select * from events_smode_test order by ev_name, a;
|
||||
@@ -166,7 +166,7 @@ drop event ee_16407_5;
|
||||
drop event ee_16407_6;
|
||||
drop procedure ee_16407_5_pendant;
|
||||
drop procedure ee_16407_6_pendant;
|
||||
set global event_scheduler= 0;
|
||||
set global event_scheduler= 2;
|
||||
drop table events_smode_test;
|
||||
set sql_mode=@old_sql_mode;
|
||||
#
|
||||
|
@@ -10,7 +10,7 @@ BEGIN
|
||||
END|
|
||||
delimiter ;|
|
||||
--echo "Check General Query Log"
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
create event log_general on schedule every 1 minute do SELect 'alabala', sleep(3) from dual;
|
||||
TRUNCATE mysql.general_log;
|
||||
--echo "1 row, the current statement!"
|
||||
@@ -22,7 +22,7 @@ SET GLOBAL event_scheduler=1;
|
||||
call select_general_log();
|
||||
DROP PROCEDURE select_general_log;
|
||||
DROP EVENT log_general;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
--sleep 1
|
||||
|
||||
--echo "Check slow query log"
|
||||
@@ -53,10 +53,10 @@ TRUNCATE mysql.slow_log;
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
--echo "Set new values"
|
||||
SET GLOBAL long_query_time=4;
|
||||
SET SESSION long_query_time=2;
|
||||
SET SESSION long_query_time=1;
|
||||
--echo "Check that logging is working"
|
||||
SELECT SLEEP(3);
|
||||
--replace_regex /00:00:0[3-5]/SLEEPVAL/
|
||||
SELECT SLEEP(2);
|
||||
--replace_regex /00:00:0[2-4]/SLEEPVAL/
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
TRUNCATE mysql.slow_log;
|
||||
CREATE TABLE slow_event_test (slo_val tinyint, val tinyint);
|
||||
@@ -73,14 +73,15 @@ SELECT * FROM slow_event_test;
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
--echo "This should go to the slow log"
|
||||
SET SESSION long_query_time=10;
|
||||
SET GLOBAL long_query_time=1;
|
||||
DROP EVENT long_event;
|
||||
CREATE EVENT long_event2 ON SCHEDULE EVERY 1 MINUTE DO INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(5);
|
||||
CREATE EVENT long_event2 ON SCHEDULE EVERY 1 MINUTE DO INSERT INTO slow_event_test SELECT @@long_query_time, SLEEP(2);
|
||||
--echo "Sleep some more time than the actual event run will take"
|
||||
--sleep 7
|
||||
--sleep 3
|
||||
--echo "Check our table. Should see 2 rows"
|
||||
SELECT * FROM slow_event_test;
|
||||
--echo "Check slow log. Should see 1 row because 5 is over the threshold of 4 for GLOBAL, though under SESSION which is 10"
|
||||
--replace_regex /00:00:0[5-7]/SLEEPVAL/
|
||||
--echo "Check slow log. Should see 1 row because 4 is over the threshold of 3 for GLOBAL, though under SESSION which is 10"
|
||||
--replace_regex /00:00:0[2-4]/SLEEPVAL/
|
||||
SELECT user_host, query_time, db, sql_text FROM mysql.slow_log;
|
||||
DROP EVENT long_event2;
|
||||
SET GLOBAL long_query_time =@old_global_long_query_time;
|
||||
|
@@ -1,55 +1,15 @@
|
||||
create database if not exists events_test;
|
||||
use events_test;
|
||||
|
||||
--error 1235
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 MICROSECOND DO SELECT 1;
|
||||
--error 1235
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 DAY_MICROSECOND DO SELECT 1;
|
||||
--error 1235
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 HOUR_MICROSECOND DO SELECT 1;
|
||||
--error 1235
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 MINUTE_MICROSECOND DO SELECT 1;
|
||||
--error 1235
|
||||
--error ER_NOT_SUPPORTED_YET
|
||||
CREATE EVENT micro_test ON SCHEDULE EVERY 100 SECOND_MICROSECOND DO SELECT 1;
|
||||
|
||||
--echo "Now create normal event and change it on SQL level"
|
||||
CREATE EVENT micro_test2 ON SCHEDULE EVERY 1 MONTH DO SELECT 1;
|
||||
UPDATE mysql.event SET interval_field='MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
--error 1235
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
UPDATE mysql.event SET interval_field='DAY_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
--error 1235
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
UPDATE mysql.event SET interval_field='SECOND_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
--error 1235
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
UPDATE mysql.event SET interval_field='HOUR_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
--error 1235
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
UPDATE mysql.event SET interval_field='MINUTE_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2';
|
||||
--error 1235
|
||||
SHOW CREATE EVENT micro_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 1
|
||||
--echo "Should not be running:"
|
||||
SHOW VARIABLES like 'event_scheduler';
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER='event_scheduler';
|
||||
DROP EVENT micro_test2;
|
||||
|
||||
drop database events_test;
|
||||
|
@@ -15,7 +15,7 @@ CREATE EVENT start_n_end
|
||||
DO INSERT INTO table_2 VALUES(1);
|
||||
--sleep 5
|
||||
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND ON COMPLETION PRESERVE DO INSERT INTO table_4 VALUES(1);
|
||||
--sleep 5
|
||||
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
|
||||
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
|
||||
@@ -28,8 +28,8 @@ DROP EVENT start_n_end;
|
||||
--echo "Already dropped because ended. Therefore an error."
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT only_one_time;
|
||||
--echo "Already dropped because ended. Therefore an error."
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
--echo "Should be preserved"
|
||||
SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS;
|
||||
DROP EVENT two_time;
|
||||
DROP TABLE table_1;
|
||||
DROP TABLE table_2;
|
||||
|
@@ -2,78 +2,124 @@ CREATE DATABASE IF NOT EXISTS events_test;
|
||||
#
|
||||
# DROP DATABASE test start (bug #16406)
|
||||
#
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
CREATE TABLE events_test.fill_it(test_name varchar(20), occur datetime);
|
||||
CREATE USER event_user2@localhost;
|
||||
CREATE DATABASE events_conn2_db;
|
||||
GRANT ALL ON *.* TO event_user2@localhost;
|
||||
CREATE USER event_user3@localhost;
|
||||
CREATE DATABASE events_conn3_db;
|
||||
GRANT ALL ON *.* TO event_user3@localhost;
|
||||
connect (conn2,localhost,event_user2,,events_conn2_db);
|
||||
--echo "In the second connection we create some events which won't be dropped till the end"
|
||||
--disable_query_log
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT conn2_ev$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn2_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
connect (conn3,localhost,event_user3,,events_conn3_db);
|
||||
--echo "In the second connection we create some events which won't be dropped till the end"
|
||||
--disable_query_log
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT conn3_ev$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn3_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
connection default;
|
||||
USE events_conn1_test2;
|
||||
CREATE EVENT ev_drop1 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
CREATE EVENT ev_drop2 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
CREATE EVENT ev_drop3 ON SCHEDULE EVERY 10 MINUTE DISABLE DO SELECT 1;
|
||||
USE events_test;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
DROP DATABASE events_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
DROP DATABASE events_conn1_test2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
|
||||
--echo "Now testing stability - dropping db -> events while they are running"
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
USE events_conn1_test2;
|
||||
--disable_query_log
|
||||
let $1= 1000;
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
|
||||
eval CREATE EVENT conn1_round1_ev$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn1_round1_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
SET GLOBAL event_scheduler=1;
|
||||
--sleep 4
|
||||
DROP DATABASE events_test2;
|
||||
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--sleep 2
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
CREATE DATABASE events_test3;
|
||||
USE events_test3;
|
||||
--disable_query_log
|
||||
let $1= 950;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test3';
|
||||
--sleep 3
|
||||
CREATE DATABASE events_test4;
|
||||
USE events_test4;
|
||||
--disable_query_log
|
||||
let $1= 860;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
|
||||
CREATE DATABASE events_test2;
|
||||
USE events_test2;
|
||||
--disable_query_log
|
||||
let $1= 1050;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT ev_drop$1 ON SCHEDULE EVERY 1 SECOND DO SELECT $1;
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_test2';
|
||||
--sleep 6
|
||||
DROP DATABASE events_test2;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
DROP DATABASE events_test3;
|
||||
DROP DATABASE events_conn1_test2;
|
||||
|
||||
SET GLOBAL event_scheduler=2;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
CREATE DATABASE events_conn1_test3;
|
||||
USE events_conn1_test3;
|
||||
--disable_query_log
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT conn1_round2_ev$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn1_round2_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
SET GLOBAL event_scheduler=1;
|
||||
DROP DATABASE events_test4;
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test3';
|
||||
CREATE DATABASE events_conn1_test4;
|
||||
USE events_conn1_test4;
|
||||
--disable_query_log
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT conn1_round3_ev$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn1_round3_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
CREATE DATABASE events_conn1_test2;
|
||||
USE events_conn1_test2;
|
||||
--disable_query_log
|
||||
let $1= 50;
|
||||
while ($1)
|
||||
{
|
||||
eval CREATE EVENT ev_round4_drop$1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_test.fill_it VALUES("conn1_round4_ev$1", NOW());
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
SELECT COUNT(*) FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='events_conn1_test2';
|
||||
--sleep 6
|
||||
connection conn2;
|
||||
--send
|
||||
DROP DATABASE events_conn2_db;
|
||||
connection conn3;
|
||||
--send
|
||||
DROP DATABASE events_conn3_db;
|
||||
connection default;
|
||||
--send
|
||||
DROP DATABASE events_conn1_test2;
|
||||
DROP DATABASE events_conn1_test3;
|
||||
SET GLOBAL event_scheduler=2;
|
||||
DROP DATABASE events_conn1_test4;
|
||||
SET GLOBAL event_scheduler=1;
|
||||
connection conn2;
|
||||
reap;
|
||||
disconnect conn2;
|
||||
connection conn3;
|
||||
reap;
|
||||
disconnect conn3;
|
||||
connection default;
|
||||
USE events_test;
|
||||
DROP TABLE fill_it;
|
||||
--disable_query_log
|
||||
DROP USER event_user2@localhost;
|
||||
DROP USER event_user3@localhost;
|
||||
--enable_query_log
|
||||
#
|
||||
# DROP DATABASE test end (bug #16406)
|
||||
#
|
||||
|
68
mysql-test/t/im_cmd_line.imtest
Normal file
68
mysql-test/t/im_cmd_line.imtest
Normal file
@@ -0,0 +1,68 @@
|
||||
###########################################################################
|
||||
#
|
||||
# Tests for user-management command-line options.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
|
||||
# List users so we are sure about starting conditions.
|
||||
|
||||
--echo --> Listing users...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
# Add a new user.
|
||||
|
||||
--echo ==> Adding user 'testuser'...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --add-user --username=testuser --password=abc 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
--echo --> IM password file:
|
||||
--exec cat $IM_PASSWORD_PATH
|
||||
--echo --> EOF
|
||||
--echo
|
||||
|
||||
--echo --> Printing out line for 'testuser'...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --passwd --username=testuser --password=abc | tail -1
|
||||
--echo
|
||||
|
||||
--echo --> Listing users...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
# Edit user's attributes.
|
||||
|
||||
--echo ==> Changing the password of 'testuser'...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --edit-user --username=testuser --password=xyz 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
--echo --> IM password file:
|
||||
--exec cat $IM_PASSWORD_PATH
|
||||
--echo --> EOF
|
||||
--echo
|
||||
|
||||
--echo --> Printing out line for 'testuser'...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --passwd --username=testuser --password=xyz | tail -1
|
||||
--echo
|
||||
|
||||
--echo --> Listing users...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
# Drop user.
|
||||
|
||||
--echo ==> Dropping user 'testuser'...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --drop-user --username=testuser 2>&1 >/dev/null
|
||||
--echo
|
||||
|
||||
--echo --> IM password file:
|
||||
--exec cat $IM_PASSWORD_PATH
|
||||
--echo --> EOF
|
||||
--echo
|
||||
|
||||
--echo --> Listing users...
|
||||
--exec $IM_EXE --defaults-file="$IM_DEFAULTS_PATH" --list-users 2>&1 >/dev/null
|
||||
--echo
|
@@ -1,2 +1,3 @@
|
||||
--run-as-service
|
||||
--log=$MYSQLTEST_VARDIR/log/im.log
|
||||
--monitoring-interval=1
|
||||
|
@@ -10,6 +10,9 @@
|
||||
|
||||
###########################################################################
|
||||
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted
|
||||
|
1
mysql-test/t/im_instance_conf-im.opt
Normal file
1
mysql-test/t/im_instance_conf-im.opt
Normal file
@@ -0,0 +1 @@
|
||||
--monitoring-interval=1
|
228
mysql-test/t/im_instance_conf.imtest
Normal file
228
mysql-test/t/im_instance_conf.imtest
Normal file
@@ -0,0 +1,228 @@
|
||||
###########################################################################
|
||||
#
|
||||
# This test suite checks the following statements:
|
||||
# - CREATE INSTANCE <instance_name> [option1[=option1_value], ...];
|
||||
# - DROP INSTANCE <instance_name>;
|
||||
#
|
||||
# For CREATE INSTANCE we check that:
|
||||
# - CREATE INSTANCE succeeds for non-existing instance;
|
||||
# - CREATE INSTANCE fails for existing instance;
|
||||
# - CREATE INSTANCE can get additional options with and w/o values;
|
||||
# - CREATE INSTANCE parses options and handles grammar errors correctly.
|
||||
# Check that strings with spaces are handled correctly, unknown (for
|
||||
# mysqld) options should also be handled;
|
||||
# - CREATE INSTANCE updates both config file and internal configuration cache;
|
||||
# - CREATE INSTANCE allows to create instances only with properly formed
|
||||
# names (mysqld*);
|
||||
#
|
||||
# For DROP INSTANCE we check that:
|
||||
# - DROP INSTANCE succeeds for existing instance;
|
||||
# - DROP INSTANCE fails for non-existing instance;
|
||||
# - DROP INSTANCE fails for active instance.
|
||||
# - DROP INSTANCE updates both config file and internal configuration cache;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Check that the configuration file contains only instances that we expect.
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# Check that mysqld1 is reported as running.
|
||||
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
# Check that the expected mysqld instance is actually run (check that we can
|
||||
# connect and execute something).
|
||||
|
||||
--echo
|
||||
--echo ---> connection: mysql1_con
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--disconnect mysql1_con
|
||||
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
--connection default
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# CREATE INSTANCE tests.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Check that CREATE INSTANCE succeeds for non-existing instance and also check
|
||||
# that both config file and internal configuration cache have been updated.
|
||||
|
||||
CREATE INSTANCE mysqld3;
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# Check that CREATE INSTANCE fails for existing instance. Let's all three
|
||||
# existing instances (running one, stopped one and just created one). Just in
|
||||
# case...
|
||||
|
||||
--error 3012 # ER_CREATE_EXISTING_INSTANCE
|
||||
CREATE INSTANCE mysqld1;
|
||||
|
||||
--error 3012 # ER_CREATE_EXISTING_INSTANCE
|
||||
CREATE INSTANCE mysqld2;
|
||||
|
||||
--error 3012 # ER_CREATE_EXISTING_INSTANCE
|
||||
CREATE INSTANCE mysqld3;
|
||||
|
||||
# Check that CREATE INSTANCE can get additional options with and w/o values.
|
||||
# Ensure that config file is updated properly.
|
||||
|
||||
# - without values;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep nonguarded $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
CREATE INSTANCE mysqld4 nonguarded;
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep nonguarded $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - with value;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-A $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-B $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
CREATE INSTANCE mysqld5 test-A = 000, test-B = test;
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-A $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-B $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# Check that CREATE INSTANCE parses options and handles grammar errors
|
||||
# correctly. Check that strings with spaces are handled correctly,
|
||||
# unknown (for mysqld) options should also be handled.
|
||||
|
||||
# - check handling of extra spaces;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-C $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
CREATE INSTANCE mysqld6 test-C1 = 10 , test-C2 = 02 ;
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-C1 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-C2 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check handling of grammar error;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-D $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-E $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
CREATE INSTANCE mysqld7 test-D = test-D-value ;
|
||||
SHOW INSTANCES;
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
CREATE INSTANCE mysqld8 test-E 0 ;
|
||||
SHOW INSTANCES;
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
CREATE INSTANCE mysqld8 test-F = ;
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-D $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-E $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check parsing of string option values
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-1 $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-2 $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-3 $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-4 $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
CREATE INSTANCE mysqld9 test-1=" hello world ", test-2=' ';
|
||||
SHOW INSTANCES;
|
||||
|
||||
CREATE INSTANCE mysqld9a test-3='\b\babc\sdef';
|
||||
# test-3='abc def'
|
||||
SHOW INSTANCES;
|
||||
|
||||
CREATE INSTANCE mysqld9b test-4='abc\tdef', test-5='abc\ndef';
|
||||
SHOW INSTANCES;
|
||||
|
||||
CREATE INSTANCE mysqld9c test-6="abc\rdef", test-7="abc\\def";
|
||||
# test-6=abc
|
||||
SHOW INSTANCES;
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
CREATE INSTANCE mysqld10 test-bad=' \ ';
|
||||
SHOW INSTANCES;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-1 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-2 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-3 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-4 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-5 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-6 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-7 $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep test-bad $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
|
||||
# Check that CREATE INSTANCE allows to create instances only with properly
|
||||
# formed names (mysqld*).
|
||||
|
||||
--error 3014 # ER_MALFORMED_INSTANCE_NAME
|
||||
CREATE INSTANCE qqq1;
|
||||
|
1
mysql-test/t/im_life_cycle-im.opt
Normal file
1
mysql-test/t/im_life_cycle-im.opt
Normal file
@@ -0,0 +1 @@
|
||||
--monitoring-interval=1
|
@@ -17,11 +17,15 @@
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.1.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
SHOW INSTANCE STATUS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
@@ -33,20 +37,22 @@ SHOW INSTANCE STATUS mysqld2;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.2.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
START INSTANCE mysqld2;
|
||||
# FIXME
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
SHOW INSTANCE STATUS mysqld2;
|
||||
|
||||
--connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
--connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD2_PORT,$IM_MYSQLD2_SOCK)
|
||||
--connection mysql_con
|
||||
|
||||
--replace_result $IM_MYSQLD1_PORT IM_MYSQLD1_PORT
|
||||
--replace_result $IM_MYSQLD2_PORT IM_MYSQLD2_PORT
|
||||
SHOW VARIABLES LIKE 'port';
|
||||
|
||||
--connection default
|
||||
@@ -61,9 +67,15 @@ SHOW VARIABLES LIKE 'port';
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.3.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
STOP INSTANCE mysqld2;
|
||||
# FIXME
|
||||
# FIXME: STOP INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to stop instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
@@ -81,16 +93,17 @@ SHOW INSTANCE STATUS mysqld2;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--error 3000
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.4.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error 3000 # ER_BAD_INSTANCE_NAME
|
||||
START INSTANCE mysqld3;
|
||||
|
||||
--error 3002
|
||||
--error 3002 # ER_INSTANCE_ALREADY_STARTED
|
||||
START INSTANCE mysqld1;
|
||||
|
||||
# FIXME TODO
|
||||
# BUG#12813: START/STOP INSTANCE commands accept a list as argument
|
||||
# START INSTANCE mysqld1, mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1.1.5. Check that Instance Manager reports correct errors for 'STOP INSTANCE'
|
||||
@@ -101,39 +114,54 @@ START INSTANCE mysqld1;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--error 3000
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.5.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error 3000 # ER_BAD_INSTANCE_NAME
|
||||
STOP INSTANCE mysqld3;
|
||||
|
||||
# TODO: IM should be fixed.
|
||||
# BUG#12673: Instance Manager allows to stop the instance many times
|
||||
# --error 3002
|
||||
# --error 3002 # ER_INSTANCE_ALREADY_STARTED
|
||||
# STOP INSTANCE mysqld2;
|
||||
|
||||
# FIXME TODO
|
||||
# BUG#12813: START/STOP INSTANCE commands accept a list as argument
|
||||
# STOP INSTANCE mysqld1, mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1.1.6. Check that Instance Manager is able to restart guarded instances.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.6.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted
|
||||
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1.1.7. Check that Instance Manager does not restart non-guarded instance.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.7.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
START INSTANCE mysqld2;
|
||||
# FIXME
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
@@ -147,7 +175,13 @@ SHOW INSTANCES;
|
||||
# incomplete SHOW INSTANCE STATUS command.
|
||||
#
|
||||
###########################################################################
|
||||
--error 1149
|
||||
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- 1.1.8.
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
SHOW INSTANCE STATUS;
|
||||
|
||||
#
|
||||
@@ -159,8 +193,13 @@ SHOW INSTANCE STATUS;
|
||||
# a list as argument.
|
||||
#
|
||||
|
||||
--error 1149
|
||||
--echo
|
||||
--echo --------------------------------------------------------------------
|
||||
--echo -- BUG#12813
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
START INSTANCE mysqld1,mysqld2,mysqld3;
|
||||
|
||||
--error 1149
|
||||
--error ER_SYNTAX_ERROR
|
||||
STOP INSTANCE mysqld1,mysqld2,mysqld3;
|
||||
|
268
mysql-test/t/im_options.imtest
Normal file
268
mysql-test/t/im_options.imtest
Normal file
@@ -0,0 +1,268 @@
|
||||
###########################################################################
|
||||
#
|
||||
# This test suite checks the following statements:
|
||||
# - SET <instance id>.<option name> = <option value>;
|
||||
# - UNSET <instance id>.<option name> = <option value>;
|
||||
# - FLUSH INSTANCES;
|
||||
#
|
||||
# For SET/UNSET we check that:
|
||||
# - SET ignores spaces correctly;
|
||||
# - UNSET does not allow option-value part (= <option value>);
|
||||
# - SET/UNSET can be applied several times w/o error;
|
||||
# - SET/UNSET is allowed only for stopped instances;
|
||||
# - SET/UNSET updates both the configuration cache in IM and
|
||||
# the configuration file;
|
||||
#
|
||||
# For FLUSH INSTANCES we check that:
|
||||
# - FLUSH INSTANCES is allowed only when all instances are stopped;
|
||||
#
|
||||
# According to the IM implementation details, we should play at least with the
|
||||
# following options:
|
||||
# - server_id
|
||||
# - port
|
||||
# - nonguarded
|
||||
|
||||
# Let's test SET statement on the option 'server_id'. It's expected that
|
||||
# originally the instances have the following server ids and states:
|
||||
# - mysqld1: server_id: 1; running (online)
|
||||
# - mysqld2: server_id: 2; stopped (offline)
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check that SET/UNSET is allowed only for stopped instances.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check that SET/UNSET is denied for running instances;
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
UNSET mysqld1.server_id;
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
SET mysqld1.server_id = 11;
|
||||
|
||||
# - check that SET/UNSET is denied for active instances:
|
||||
# - create dummy misconfigured instance;
|
||||
# - start it;
|
||||
# - try to set/unset options;
|
||||
|
||||
CREATE INSTANCE mysqld3 datadir = '/';
|
||||
START INSTANCE mysqld3;
|
||||
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
# NOTE: We can not analyze state of the instance here -- it can be Failed or
|
||||
# Starting because Instance Manager is trying to start the misconfigured
|
||||
# instance several times.
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
UNSET mysqld3.server_id;
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
SET mysqld3.server_id = 11;
|
||||
|
||||
STOP INSTANCE mysqld3;
|
||||
|
||||
# FIXME: STOP INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to stop instance.
|
||||
|
||||
--replace_column 3 VERSION_NUMBER 4 VERSION
|
||||
SHOW INSTANCE STATUS mysqld3;
|
||||
|
||||
# - check that SET/UNSET succeed for stopped instances;
|
||||
# - check that SET/UNSET can be applied multiple times;
|
||||
|
||||
UNSET mysqld2.server_id;
|
||||
UNSET mysqld2.server_id;
|
||||
|
||||
--replace_column 2 option_value
|
||||
SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
SET mysqld2.server_id = 2;
|
||||
SET mysqld2.server_id = 2;
|
||||
|
||||
--replace_column 2 option_value
|
||||
SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
# - check that UNSET does not allow option-value part (= <option value>);
|
||||
|
||||
--error ER_SYNTAX_ERROR
|
||||
UNSET mysqld2.server_id = 11;
|
||||
|
||||
# - check that SET/UNSET working properly with multiple options;
|
||||
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc = 0010, mysqld3.ddd = 0020;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ccc $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ddd $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
UNSET mysqld2.aaa, mysqld3.bbb, mysqld2.ccc, mysqld3.ddd;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ccc $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ddd $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check that if some instance name is invalid or the active is active,
|
||||
# whole SET-statement will not be executed;
|
||||
|
||||
--error 3000 # ER_BAD_INSTANCE_NAME
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld.ccc = 0010;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ccc $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
SET mysqld2.aaa, mysqld3.bbb, mysqld1.ccc = 0010;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep ccc $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check that if some instance name is invalid or the active is active,
|
||||
# whole UNSET-statement will not be executed;
|
||||
|
||||
--error 3000 # ER_BAD_INSTANCE_NAME
|
||||
UNSET mysqld2.server_id, mysqld3.server_id, mysqld.ccc;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
--error 3015 # ER_INSTANCE_IS_ACTIVE
|
||||
UNSET mysqld2.server_id, mysqld3.server_id, mysqld1.ccc;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
DROP INSTANCE mysqld3;
|
||||
|
||||
# - check that spaces are handled correctly;
|
||||
|
||||
SET mysqld2.server_id=222;
|
||||
SET mysqld2.server_id = 222;
|
||||
SET mysqld2.server_id = 222 ;
|
||||
SET mysqld2 . server_id = 222 ;
|
||||
SET mysqld2 . server_id = 222 , mysqld2 . aaa , mysqld2 . bbb ;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
UNSET mysqld2 . aaa , mysqld2 . bbb ;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep aaa $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep bbb $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check that SET/UNSET updates both the configuration cache in IM and
|
||||
# the configuration file.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check that the configuration file has been updated (i.e. contains
|
||||
# server_id=SERVER_ID for mysqld2);
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns zero;
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check that internal cache of Instance Manager has been affected;
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check that FLUSH INSTANCES is allowed only when all instances are stopped.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
--error 3016 # ER_THERE_IS_ACTIVE_INSTACE
|
||||
FLUSH INSTANCES;
|
||||
|
||||
STOP INSTANCE mysqld1;
|
||||
# FIXME: STOP INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to stop instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
FLUSH INSTANCES;
|
@@ -1,142 +0,0 @@
|
||||
###########################################################################
|
||||
#
|
||||
# This file contains test for (3) test suite.
|
||||
#
|
||||
# Consult WL#2789 for more information.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Check the options-management commands:
|
||||
# - SET;
|
||||
# - FLUSH INSTANCES;
|
||||
#
|
||||
# Let's test the commands on the option 'server_id'. It's expected that
|
||||
# originally the instances have the following server ids:
|
||||
# - mysqld1: 1
|
||||
# - mysqld2: 2
|
||||
#
|
||||
# 1. SET <instance_id>.server_id= SERVER_ID); where SERVER_ID is 11 or 12.
|
||||
# 1.1. check that the configuration file has been updated (i.e. contains
|
||||
# server_id=SERVER_ID for the instance);
|
||||
# 1.2. (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns zero;
|
||||
# 1.3. check that internal cache of Instance Manager has not been affected
|
||||
# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
|
||||
#
|
||||
# 2. FLUSH INSTANCES;
|
||||
# 2.1. check that the configuration file has not been updated;
|
||||
# 2.2. (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns zero value;
|
||||
# 2.3. check that internal cache of Instance Manager has been updated (i.e.
|
||||
# SHOW INSTANCE OPTIONS <instance> contains 'server_id=SERVER_ID' line).
|
||||
#
|
||||
# 3. Restore options.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 0. Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1. SET <instance_id>.server_id= SERVER_ID); where SERVER_ID is 11 or 12.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# * mysqld1
|
||||
|
||||
SET mysqld1.server_id = 11;
|
||||
|
||||
# - check that the configuration file has been updated (i.e. contains
|
||||
# server_id=SERVER_ID for the instance);
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns zero;
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check that internal cache of Instance Manager has not been affected
|
||||
# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
|
||||
# * mysqld2
|
||||
|
||||
SET mysqld2.server_id = 12;
|
||||
|
||||
# - check that the configuration file has been updated (i.e. contains
|
||||
# server_id=SERVER_ID for the instance);
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check that internal cache of Instance Manager has not been affected
|
||||
# (i.e. SHOW INSTANCE OPTIONS <instance> does not contain updated value).
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 2. FLUSH INSTANCES;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
FLUSH INSTANCES;
|
||||
|
||||
# - check that the configuration file has not been updated;
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns zero value;
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check that internal cache of Instance Manager has been updated (i.e.
|
||||
# SHOW INSTANCE OPTIONS <instance> contains 'server_id=' line).
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
@@ -1,150 +0,0 @@
|
||||
###########################################################################
|
||||
#
|
||||
# This file contains test for (3) test suite.
|
||||
#
|
||||
# Consult WL#2789 for more information.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#
|
||||
# Check the options-management commands:
|
||||
# - UNSET;
|
||||
# - FLUSH INSTANCES;
|
||||
#
|
||||
# Let's test the commands on the option 'server_id'. It's expected that
|
||||
# originally the instances have the following server ids:
|
||||
# - mysqld1: 1
|
||||
# - mysqld2: 2
|
||||
#
|
||||
# The test case:
|
||||
#
|
||||
# 1. UNSET <instance_id>.server_id;
|
||||
#
|
||||
# Do the step for both instances.
|
||||
#
|
||||
# 1.1. check that the configuration file has been updated (i.e. does not
|
||||
# contain 'server_id=' line for the instance);
|
||||
# 1.2. (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns non-zero value;
|
||||
# 1.3. check that internal cache of Instance Manager is not affected (i.e.
|
||||
# SHOW INSTANCE OPTIONS <instance> contains non-zero value for server_id);
|
||||
#
|
||||
# 2. FLUSH INSTANCES;
|
||||
#
|
||||
# Do the step for both instances.
|
||||
#
|
||||
# 2.1. check that the configuration file has not been updated (i.e. does not
|
||||
# contain 'server_id=' for the instance);
|
||||
# 2.2. (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns non-zero value;
|
||||
# 2.3. check that internal cache of Instance Manager has been updated (i.e.
|
||||
# SHOW INSTANCE OPTIONS <instance> does not contain 'server_id=' line).
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 0. Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 1. UNSET <instance_id>.server_id;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# * mysqld1
|
||||
|
||||
UNSET mysqld1.server_id;
|
||||
|
||||
# - check that the configuration file has been updated (i.e. does not
|
||||
# contain 'server_id=' line for the instance);
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf ;
|
||||
|
||||
# - check that the running instance has not been affected: connect to the
|
||||
# instance and check that 'SHOW VARIABLES LIKE 'server_id'' returns non-zero
|
||||
# value;
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check that internal cache of Instance Manager is not affected (i.e. SHOW
|
||||
# INSTANCE OPTIONS <instance> contains non-zero value for server_id);
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
|
||||
# * mysqld2
|
||||
|
||||
UNSET mysqld2.server_id;
|
||||
|
||||
# - check that the configuration file has been updated (i.e. does not
|
||||
# contain 'server_id=' line for the instance);
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
|
||||
# - check that internal cache of Instance Manager is not affected (i.e. SHOW
|
||||
# INSTANCE OPTIONS <instance> contains non-zero value for server_id);
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 2. FLUSH INSTANCES;
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
FLUSH INSTANCES;
|
||||
|
||||
# - check that the configuration file has not been updated (i.e. does not
|
||||
# contain 'server_id=' for the instance);
|
||||
|
||||
--exec grep server_id $MYSQLTEST_VARDIR/im.cnf || true;
|
||||
|
||||
# - (for mysqld1) check that the running instance has not been affected:
|
||||
# connect to the instance and check that 'SHOW VARIABLES LIKE 'server_id''
|
||||
# returns non-zero value;
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check that internal cache of Instance Manager has been updated (i.e.
|
||||
# SHOW INSTANCE OPTIONS <instance> does not contain 'server_id=' line).
|
||||
# TODO: we should check only server_id option here.
|
||||
|
||||
# SHOW INSTANCE OPTIONS mysqld1;
|
||||
# SHOW INSTANCE OPTIONS mysqld2;
|
1
mysql-test/t/im_utils-im.opt
Normal file
1
mysql-test/t/im_utils-im.opt
Normal file
@@ -0,0 +1 @@
|
||||
--monitoring-interval=1
|
@@ -17,6 +17,9 @@
|
||||
# - the second instance is offline;
|
||||
#
|
||||
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
SHOW INSTANCES;
|
||||
|
||||
#
|
||||
@@ -41,8 +44,9 @@ SHOW INSTANCE OPTIONS mysqld2;
|
||||
|
||||
START INSTANCE mysqld2;
|
||||
|
||||
# FIXME
|
||||
-- sleep 3
|
||||
# FIXME: START INSTANCE should be synchronous.
|
||||
--sleep 3
|
||||
# should be longer than monitoring interval and enough to start instance.
|
||||
|
||||
STOP INSTANCE mysqld2;
|
||||
|
||||
|
@@ -16,7 +16,7 @@ use mysql;
|
||||
#
|
||||
|
||||
truncate table general_log;
|
||||
--replace_column 1 TIMESTAMP
|
||||
--replace_column 1 TIMESTAMP 3 THREAD_ID
|
||||
select * from general_log;
|
||||
truncate table slow_log;
|
||||
--replace_column 1 TIMESTAMP
|
||||
@@ -31,7 +31,7 @@ select * from slow_log;
|
||||
#
|
||||
|
||||
truncate table general_log;
|
||||
--replace_column 1 TIMESTAMP
|
||||
--replace_column 1 TIMESTAMP 3 THREAD_ID
|
||||
select * from general_log where argument like '%general_log%';
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ truncate table mysql.general_log;
|
||||
set names utf8;
|
||||
create table bug16905 (s char(15) character set utf8 default 'пусто');
|
||||
insert into bug16905 values ('новое');
|
||||
--replace_column 1 TIMESTAMP
|
||||
--replace_column 1 TIMESTAMP 3 THREAD_ID
|
||||
select * from mysql.general_log;
|
||||
drop table bug16905;
|
||||
|
||||
|
@@ -244,7 +244,8 @@ err:
|
||||
handle_option_ctx structure.
|
||||
group_name The name of the group the option belongs to.
|
||||
option The very option to be processed. It is already
|
||||
prepared to be used in argv (has -- prefix)
|
||||
prepared to be used in argv (has -- prefix). If it
|
||||
is NULL, we are handling a new group (section).
|
||||
|
||||
DESCRIPTION
|
||||
This handler checks whether a group is one of the listed and adds an option
|
||||
@@ -263,6 +264,9 @@ static int handle_default_option(void *in_ctx, const char *group_name,
|
||||
char *tmp;
|
||||
struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
|
||||
|
||||
if (!option)
|
||||
return 0;
|
||||
|
||||
if (find_type((char *)group_name, ctx->group, 3))
|
||||
{
|
||||
if (!(tmp= alloc_root(ctx->alloc, (uint) strlen(option) + 1)))
|
||||
@@ -719,6 +723,10 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
|
||||
end[0]=0;
|
||||
|
||||
strnmov(curr_gr, ptr, min((uint) (end-ptr)+1, 4096));
|
||||
|
||||
/* signal that a new group is found */
|
||||
opt_handler(handler_ctx, curr_gr, NULL);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (!found_group)
|
||||
|
@@ -40,11 +40,13 @@ static char *add_option(char *dst, const char *option_value,
|
||||
SYNOPSYS
|
||||
modify_defaults_file()
|
||||
file_location The location of configuration file to edit
|
||||
option option to look for
|
||||
option value The value of the option we would like to set
|
||||
section_name the name of the section
|
||||
remove_option This is true if we want to remove the option.
|
||||
False otherwise.
|
||||
option The name of the option to look for (can be NULL)
|
||||
option value The value of the option we would like to set (can be NULL)
|
||||
section_name The name of the section (must be NOT NULL)
|
||||
remove_option This defines what we want to remove:
|
||||
- MY_REMOVE_NONE -- nothing to remove;
|
||||
- MY_REMOVE_OPTION -- remove the specified option;
|
||||
- MY_REMOVE_SECTION -- remove the specified section;
|
||||
IMPLEMENTATION
|
||||
We open the option file first, then read the file line-by-line,
|
||||
looking for the section we need. At the same time we put these lines
|
||||
@@ -67,7 +69,9 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
FILE *cnf_file;
|
||||
MY_STAT file_stat;
|
||||
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
|
||||
uint opt_len, optval_len, sect_len, nr_newlines= 0, buffer_size;
|
||||
uint opt_len= 0;
|
||||
uint optval_len= 0;
|
||||
uint sect_len, nr_newlines= 0, buffer_size;
|
||||
my_bool in_section= FALSE, opt_applied= 0;
|
||||
uint reserve_extended;
|
||||
uint new_opt_len;
|
||||
@@ -81,8 +85,11 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
|
||||
goto malloc_err;
|
||||
|
||||
if (option && option_value)
|
||||
{
|
||||
opt_len= (uint) strlen(option);
|
||||
optval_len= (uint) strlen(option_value);
|
||||
}
|
||||
|
||||
new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
|
||||
|
||||
@@ -119,8 +126,8 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* correct the option */
|
||||
if (in_section && !strncmp(src_ptr, option, opt_len) &&
|
||||
/* correct the option (if requested) */
|
||||
if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
|
||||
(*(src_ptr + opt_len) == '=' ||
|
||||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
|
||||
*(src_ptr + opt_len) == '\0'))
|
||||
@@ -143,7 +150,12 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If going to new group and we have option to apply, do it now */
|
||||
/*
|
||||
If we are going to the new group and have an option to apply, do
|
||||
it now. If we are removing a single option or the whole section
|
||||
this will only trigger opt_applied flag.
|
||||
*/
|
||||
|
||||
if (in_section && !opt_applied && *src_ptr == '[')
|
||||
{
|
||||
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||
@@ -153,6 +165,9 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
|
||||
for (; nr_newlines; nr_newlines--)
|
||||
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||
|
||||
/* Skip the section if MY_REMOVE_SECTION was given */
|
||||
if (!in_section || remove_option != MY_REMOVE_SECTION)
|
||||
dst_ptr= strmov(dst_ptr, linebuff);
|
||||
}
|
||||
/* Look for a section */
|
||||
@@ -167,18 +182,31 @@ int modify_defaults_file(const char *file_location, const char *option,
|
||||
{}
|
||||
|
||||
if (*src_ptr != ']')
|
||||
{
|
||||
in_section= FALSE;
|
||||
continue; /* Missing closing parenthesis. Assume this was no group */
|
||||
}
|
||||
|
||||
if (remove_option == MY_REMOVE_SECTION)
|
||||
dst_ptr= dst_ptr - strlen(linebuff);
|
||||
|
||||
in_section= TRUE;
|
||||
}
|
||||
else
|
||||
in_section= FALSE; /* mark that this section is of no interest to us */
|
||||
}
|
||||
}
|
||||
/* File ended. */
|
||||
if (!opt_applied && !remove_option && in_section)
|
||||
|
||||
/*
|
||||
File ended. Apply an option or set opt_applied flag (in case of
|
||||
MY_REMOVE_SECTION) so that the changes are saved. Do not do anything
|
||||
if we are removing non-existent option.
|
||||
*/
|
||||
|
||||
if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION))
|
||||
{
|
||||
/* New option still remains to apply at the end */
|
||||
if (*(dst_ptr - 1) != '\n')
|
||||
if (!remove_option && *(dst_ptr - 1) != '\n')
|
||||
dst_ptr= strmov(dst_ptr, NEWLINE);
|
||||
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
|
||||
opt_applied= 1;
|
||||
|
@@ -9,6 +9,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc
|
||||
instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
|
||||
mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
|
||||
thread_registry.cc user_map.cc imservice.cpp windowsservice.cpp
|
||||
user_management_commands.cc
|
||||
../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
|
||||
../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
|
||||
../../libmysql/errmsg.c)
|
||||
|
@@ -30,15 +30,14 @@ void IMService::Run(DWORD argc, LPTSTR *argv)
|
||||
// report to the SCM that we're about to start
|
||||
ReportStatus((DWORD)SERVICE_START_PENDING);
|
||||
|
||||
Options o;
|
||||
o.load(argc, argv);
|
||||
Options::load(argc, argv);
|
||||
|
||||
// init goes here
|
||||
ReportStatus((DWORD)SERVICE_RUNNING);
|
||||
|
||||
// wait for main loop to terminate
|
||||
manager(o);
|
||||
o.cleanup();
|
||||
manager();
|
||||
Options::cleanup();
|
||||
}
|
||||
|
||||
void IMService::Log(const char *msg)
|
||||
@@ -46,13 +45,13 @@ void IMService::Log(const char *msg)
|
||||
log_info(msg);
|
||||
}
|
||||
|
||||
int HandleServiceOptions(Options options)
|
||||
int HandleServiceOptions()
|
||||
{
|
||||
int ret_val= 0;
|
||||
|
||||
IMService winService;
|
||||
|
||||
if (options.install_as_service)
|
||||
if (Options::Service::install_as_service)
|
||||
{
|
||||
if (winService.IsInstalled())
|
||||
log_info("Service is already installed");
|
||||
@@ -64,7 +63,7 @@ int HandleServiceOptions(Options options)
|
||||
ret_val= 1;
|
||||
}
|
||||
}
|
||||
else if (options.remove_service)
|
||||
else if (Options::Service::remove_service)
|
||||
{
|
||||
if (! winService.IsInstalled())
|
||||
log_info("Service is not installed");
|
||||
@@ -77,6 +76,19 @@ int HandleServiceOptions(Options options)
|
||||
}
|
||||
}
|
||||
else
|
||||
ret_val= !winService.Init();
|
||||
{
|
||||
log_info("Initializing Instance Manager service...");
|
||||
|
||||
if (!winService.Init())
|
||||
{
|
||||
log_info("Service failed to initialize.");
|
||||
fprintf(stderr,
|
||||
"The service should be started by Windows Service Manager.\n"
|
||||
"The MySQL Manager should be started with '--standalone'\n"
|
||||
"to run from command line.");
|
||||
ret_val= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2006 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "windowsservice.h"
|
||||
|
||||
@@ -12,3 +30,5 @@ protected:
|
||||
void Stop();
|
||||
void Run(DWORD argc, LPTSTR *argv);
|
||||
};
|
||||
|
||||
extern int HandleServiceOptions();
|
||||
|
@@ -76,7 +76,10 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
|
||||
guardian.cc guardian.h \
|
||||
parse_output.cc parse_output.h \
|
||||
mysql_manager_error.h \
|
||||
portability.h
|
||||
portability.h \
|
||||
exit_codes.h \
|
||||
user_management_commands.h \
|
||||
user_management_commands.cc
|
||||
|
||||
mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \
|
||||
liboptions.la \
|
||||
|
@@ -7,9 +7,9 @@ static WindowsService *gService;
|
||||
WindowsService::WindowsService(void) :
|
||||
statusCheckpoint(0),
|
||||
serviceName(NULL),
|
||||
inited(false),
|
||||
inited(FALSE),
|
||||
dwAcceptedControls(SERVICE_ACCEPT_STOP),
|
||||
debugging(false)
|
||||
debugging(FALSE)
|
||||
{
|
||||
gService= this;
|
||||
status.dwServiceType= SERVICE_WIN32_OWN_PROCESS;
|
||||
@@ -22,11 +22,12 @@ WindowsService::~WindowsService(void)
|
||||
|
||||
BOOL WindowsService::Install()
|
||||
{
|
||||
bool ret_val= false;
|
||||
bool ret_val= FALSE;
|
||||
SC_HANDLE newService;
|
||||
SC_HANDLE scm;
|
||||
|
||||
if (IsInstalled()) return true;
|
||||
if (IsInstalled())
|
||||
return TRUE;
|
||||
|
||||
// determine the name of the currently executing file
|
||||
char szFilePath[_MAX_PATH];
|
||||
@@ -34,7 +35,7 @@ BOOL WindowsService::Install()
|
||||
|
||||
// open a connection to the SCM
|
||||
if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
|
||||
return false;
|
||||
return FALSE;
|
||||
|
||||
newService= CreateService(scm, serviceName, displayName,
|
||||
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
|
||||
@@ -45,7 +46,7 @@ BOOL WindowsService::Install()
|
||||
if (newService)
|
||||
{
|
||||
CloseServiceHandle(newService);
|
||||
ret_val= true;
|
||||
ret_val= TRUE;
|
||||
}
|
||||
|
||||
CloseServiceHandle(scm);
|
||||
@@ -56,34 +57,35 @@ BOOL WindowsService::Init()
|
||||
{
|
||||
assert(serviceName != NULL);
|
||||
|
||||
if (inited) return true;
|
||||
if (inited)
|
||||
return TRUE;
|
||||
|
||||
SERVICE_TABLE_ENTRY stb[] =
|
||||
{
|
||||
{ (LPSTR)serviceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
inited= true;
|
||||
inited= TRUE;
|
||||
return StartServiceCtrlDispatcher(stb); //register with the Service Manager
|
||||
}
|
||||
|
||||
BOOL WindowsService::Remove()
|
||||
{
|
||||
bool ret_val= false;
|
||||
bool ret_val= FALSE;
|
||||
|
||||
if (! IsInstalled())
|
||||
return true;
|
||||
if (!IsInstalled())
|
||||
return TRUE;
|
||||
|
||||
// open a connection to the SCM
|
||||
SC_HANDLE scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
|
||||
if (! scm)
|
||||
return false;
|
||||
if (!scm)
|
||||
return FALSE;
|
||||
|
||||
SC_HANDLE service= OpenService(scm, serviceName, DELETE);
|
||||
if (service)
|
||||
{
|
||||
if (DeleteService(service))
|
||||
ret_val= true;
|
||||
ret_val= TRUE;
|
||||
DWORD dw= ::GetLastError();
|
||||
CloseServiceHandle(service);
|
||||
}
|
||||
@@ -116,7 +118,8 @@ void WindowsService::SetAcceptedControls(DWORD acceptedControls)
|
||||
BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
|
||||
DWORD dwError)
|
||||
{
|
||||
if(debugging) return TRUE;
|
||||
if (debugging)
|
||||
return TRUE;
|
||||
|
||||
if(currentState == SERVICE_START_PENDING)
|
||||
status.dwControlsAccepted= 0;
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2006 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class WindowsService
|
||||
|
@@ -22,10 +22,12 @@
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
/* Class responsible for allocation of im commands. */
|
||||
/* Class responsible for allocation of IM commands. */
|
||||
|
||||
class Instance_map;
|
||||
|
||||
struct st_net;
|
||||
|
||||
/*
|
||||
Command - entry point for any command.
|
||||
GangOf4: 'Command' design pattern
|
||||
@@ -37,8 +39,18 @@ public:
|
||||
Command(Instance_map *instance_map_arg= 0);
|
||||
virtual ~Command();
|
||||
|
||||
/* method of executing: */
|
||||
virtual int execute(struct st_net *net, ulong connection_id) = 0;
|
||||
/*
|
||||
This operation incapsulates behaviour of the command.
|
||||
|
||||
SYNOPSYS
|
||||
net The network connection to the client.
|
||||
connection_id Client connection ID
|
||||
|
||||
RETURN
|
||||
0 On success
|
||||
non 0 On error. Client error code is returned.
|
||||
*/
|
||||
virtual int execute(st_net *net, ulong connection_id) = 0;
|
||||
|
||||
protected:
|
||||
Instance_map *instance_map;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,20 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <hash.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "instance.h"
|
||||
#include "parse.h"
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Print all instances of this instance manager.
|
||||
Grammar: SHOW ISTANCES
|
||||
@@ -31,12 +41,16 @@ public:
|
||||
Show_instances(Instance_map *instance_map_arg): Command(instance_map_arg)
|
||||
{}
|
||||
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
int write_header(st_net *net);
|
||||
int write_data(st_net *net);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Reread configuration file and refresh instance map.
|
||||
Reread configuration file and refresh internal cache.
|
||||
Grammar: FLUSH INSTANCES
|
||||
*/
|
||||
|
||||
@@ -46,7 +60,43 @@ public:
|
||||
Flush_instances(Instance_map *instance_map_arg): Command(instance_map_arg)
|
||||
{}
|
||||
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Abstract class for Instance-specific commands.
|
||||
*/
|
||||
|
||||
class Abstract_instance_cmd : public Command
|
||||
{
|
||||
public:
|
||||
Abstract_instance_cmd(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
public:
|
||||
virtual int execute(st_net *net, ulong connection_id);
|
||||
|
||||
protected:
|
||||
/* MT-NOTE: this operation is called under acquired Instance_map's lock. */
|
||||
virtual int execute_impl(st_net *net, Instance *instance) = 0;
|
||||
|
||||
/*
|
||||
This operation is invoked on successful return of execute_impl() and is
|
||||
intended to send closing data.
|
||||
|
||||
MT-NOTE: this operation is called under released Instance_map's lock.
|
||||
*/
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id) = 0;
|
||||
|
||||
protected:
|
||||
inline const LEX_STRING *get_instance_name() const
|
||||
{
|
||||
return instance_name.get_str();
|
||||
}
|
||||
|
||||
private:
|
||||
Instance_name instance_name;
|
||||
};
|
||||
|
||||
|
||||
@@ -55,31 +105,40 @@ public:
|
||||
Grammar: SHOW ISTANCE STATUS <instance_name>
|
||||
*/
|
||||
|
||||
class Show_instance_status : public Command
|
||||
class Show_instance_status : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
|
||||
Show_instance_status(Instance_map *instance_map_arg,
|
||||
const char *name, uint len);
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
const char *instance_name;
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
int write_header(st_net *net);
|
||||
int write_data(st_net *net, Instance *instance);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Print options if chosen instance.
|
||||
Print options of chosen instance.
|
||||
Grammar: SHOW INSTANCE OPTIONS <instance_name>
|
||||
*/
|
||||
|
||||
class Show_instance_options : public Command
|
||||
class Show_instance_options : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
|
||||
Show_instance_options(Instance_map *instance_map_arg,
|
||||
const char *name, uint len);
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
const char *instance_name;
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
int write_header(st_net *net);
|
||||
int write_data(st_net *net, Instance *instance);
|
||||
};
|
||||
|
||||
|
||||
@@ -88,14 +147,15 @@ public:
|
||||
Grammar: START INSTANCE <instance_name>
|
||||
*/
|
||||
|
||||
class Start_instance : public Command
|
||||
class Start_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Start_instance(Instance_map *instance_map_arg, const char *name, uint len);
|
||||
Start_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
const char *instance_name;
|
||||
Instance *instance;
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
|
||||
@@ -104,33 +164,95 @@ public:
|
||||
Grammar: STOP INSTANCE <instance_name>
|
||||
*/
|
||||
|
||||
class Stop_instance : public Command
|
||||
class Stop_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Stop_instance(Instance_map *instance_map_arg, const char *name, uint len);
|
||||
Stop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
Instance *instance;
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
const char *instance_name;
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Print requested part of the log
|
||||
Grammar:
|
||||
SHOW <instance_name> log {ERROR | SLOW | GENERAL} size[, offset_from_end]
|
||||
Create an instance.
|
||||
Grammar: CREATE INSTANCE <instance_name> [<options>]
|
||||
*/
|
||||
|
||||
class Show_instance_log : public Command
|
||||
class Create_instance : public Command
|
||||
{
|
||||
public:
|
||||
Create_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
Show_instance_log(Instance_map *instance_map_arg, const char *name,
|
||||
uint len, Log_type log_type_arg, const char *size_arg,
|
||||
const char *offset_arg);
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
public:
|
||||
bool init(const char **text);
|
||||
|
||||
protected:
|
||||
virtual int execute(st_net *net, ulong connection_id);
|
||||
|
||||
inline const LEX_STRING *get_instance_name() const
|
||||
{
|
||||
return instance_name.get_str();
|
||||
}
|
||||
|
||||
private:
|
||||
bool parse_args(const char **text);
|
||||
|
||||
private:
|
||||
Instance_name instance_name;
|
||||
|
||||
Named_value_arr options;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Drop an instance.
|
||||
Grammar: DROP INSTANCE <instance_name>
|
||||
|
||||
Operation is permitted only if the instance is stopped. On successful
|
||||
completion the instance section is removed from config file and the instance
|
||||
is removed from the instance map.
|
||||
*/
|
||||
|
||||
class Drop_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Drop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Print requested part of the log.
|
||||
Grammar:
|
||||
SHOW <instance_name> LOG {ERROR | SLOW | GENERAL} size[, offset_from_end]
|
||||
*/
|
||||
|
||||
class Show_instance_log : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Show_instance_log(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg,
|
||||
Log_type log_type_arg, uint size_arg, uint offset_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
int check_params(Instance *instance);
|
||||
int write_header(st_net *net);
|
||||
int write_data(st_net *net, Instance *instance);
|
||||
|
||||
private:
|
||||
Log_type log_type;
|
||||
const char *instance_name;
|
||||
uint size;
|
||||
uint offset;
|
||||
};
|
||||
@@ -141,75 +263,112 @@ public:
|
||||
Grammar: SHOW <instance_name> LOG FILES
|
||||
*/
|
||||
|
||||
class Show_instance_log_files : public Command
|
||||
class Show_instance_log_files : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
|
||||
Show_instance_log_files(Instance_map *instance_map_arg,
|
||||
const char *name, uint len);
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
const char *instance_name;
|
||||
const char *option;
|
||||
const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
virtual int send_ok_response(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
int write_header(st_net *net);
|
||||
int write_data(st_net *net, Instance *instance);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Syntax error command. This command is issued if parser reported a syntax
|
||||
error. We need it to distinguish the parse error and the situation when
|
||||
parser internal error occured. E.g. parsing failed because we hadn't had
|
||||
enought memory. In the latter case parse_command() should return an error.
|
||||
Abstract class for option-management commands.
|
||||
*/
|
||||
|
||||
class Instance_options_list;
|
||||
|
||||
class Abstract_option_cmd : public Command
|
||||
{
|
||||
public:
|
||||
~Abstract_option_cmd();
|
||||
|
||||
public:
|
||||
bool add_option(const LEX_STRING *instance_name, Named_value *option);
|
||||
|
||||
public:
|
||||
bool init(const char **text);
|
||||
|
||||
virtual int execute(st_net *net, ulong connection_id);
|
||||
|
||||
protected:
|
||||
Abstract_option_cmd(Instance_map *instance_map_arg);
|
||||
|
||||
int correct_file(Instance *instance, Named_value *option, bool skip);
|
||||
|
||||
protected:
|
||||
virtual bool parse_args(const char **text) = 0;
|
||||
virtual int process_option(Instance *instance, Named_value *option) = 0;
|
||||
|
||||
private:
|
||||
Instance_options_list *
|
||||
get_instance_options_list(const LEX_STRING *instance_name);
|
||||
|
||||
int execute_impl(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
HASH instance_options_map;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Set an option for the instance.
|
||||
Grammar: SET instance_name.option[=option_value][, ...]
|
||||
*/
|
||||
|
||||
class Set_option : public Abstract_option_cmd
|
||||
{
|
||||
public:
|
||||
Set_option(Instance_map *instance_map_arg);
|
||||
|
||||
protected:
|
||||
virtual bool parse_args(const char **text);
|
||||
virtual int process_option(Instance *instance, Named_value *option);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Remove option of the instance.
|
||||
Grammar: UNSET instance_name.option[, ...]
|
||||
*/
|
||||
|
||||
class Unset_option: public Abstract_option_cmd
|
||||
{
|
||||
public:
|
||||
Unset_option(Instance_map *instance_map_arg);
|
||||
|
||||
protected:
|
||||
virtual bool parse_args(const char **text);
|
||||
virtual int process_option(Instance *instance, Named_value *option);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Syntax error command.
|
||||
|
||||
This command is issued if parser reported a syntax error. We need it to
|
||||
distinguish between syntax error and internal parser error. E.g. parsing
|
||||
failed because we hadn't had enought memory. In the latter case the parser
|
||||
just returns NULL.
|
||||
*/
|
||||
|
||||
class Syntax_error : public Command
|
||||
{
|
||||
public:
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
/*
|
||||
Set an option for the instance.
|
||||
Grammar: SET instance_name.option=option_value
|
||||
*/
|
||||
|
||||
class Set_option : public Command
|
||||
{
|
||||
public:
|
||||
Set_option(Instance_map *instance_map_arg, const char *name, uint len,
|
||||
const char *option_arg, uint option_len,
|
||||
const char *option_value_arg, uint option_value_len);
|
||||
/*
|
||||
the following function is virtual to let Unset_option to use
|
||||
*/
|
||||
virtual int do_command(struct st_net *net);
|
||||
int execute(struct st_net *net, ulong connection_id);
|
||||
protected:
|
||||
int correct_file(int skip);
|
||||
public:
|
||||
const char *instance_name;
|
||||
uint instance_name_len;
|
||||
/* buffer for the option */
|
||||
enum { MAX_OPTION_LEN= 1024 };
|
||||
char option[MAX_OPTION_LEN];
|
||||
char option_value[MAX_OPTION_LEN];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Remove option of the instance from config file
|
||||
Grammar: UNSET instance_name.option
|
||||
*/
|
||||
|
||||
class Unset_option: public Set_option
|
||||
{
|
||||
public:
|
||||
Unset_option(Instance_map *instance_map_arg, const char *name, uint len,
|
||||
const char *option_arg, uint option_len,
|
||||
const char *option_value_arg, uint option_value_len):
|
||||
Set_option(instance_map_arg, name, len, option_arg, option_len,
|
||||
option_value_arg, option_value_len)
|
||||
/* This is just to avoid compiler warning. */
|
||||
Syntax_error() :Command(NULL)
|
||||
{}
|
||||
int do_command(struct st_net *net);
|
||||
};
|
||||
|
||||
public:
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H */
|
||||
|
41
server-tools/instance-manager/exit_codes.h
Normal file
41
server-tools/instance-manager/exit_codes.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
|
||||
#define INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
|
||||
|
||||
/*
|
||||
Copyright (C) 2006 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains a list of exit codes, which are used when Instance
|
||||
Manager is working in user-management mode.
|
||||
*/
|
||||
|
||||
const int ERR_OK = 0;
|
||||
|
||||
const int ERR_OUT_OF_MEMORY = 1;
|
||||
const int ERR_INVALID_USAGE = 2;
|
||||
const int ERR_INTERNAL_ERROR = 3;
|
||||
const int ERR_IO_ERROR = 4;
|
||||
const int ERR_PASSWORD_FILE_CORRUPTED = 5;
|
||||
const int ERR_PASSWORD_FILE_DOES_NOT_EXIST = 6;
|
||||
|
||||
const int ERR_CAN_NOT_READ_USER_NAME = 10;
|
||||
const int ERR_CAN_NOT_READ_PASSWORD = 11;
|
||||
const int ERR_USER_ALREADY_EXISTS = 12;
|
||||
const int ERR_USER_NOT_FOUND = 13;
|
||||
|
||||
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_EXIT_CODES_H
|
@@ -21,16 +21,14 @@
|
||||
|
||||
#include "guardian.h"
|
||||
|
||||
#include "instance_map.h"
|
||||
#include "instance.h"
|
||||
#include "mysql_manager_error.h"
|
||||
#include "log.h"
|
||||
#include "portability.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "instance.h"
|
||||
#include "instance_map.h"
|
||||
#include "log.h"
|
||||
#include "mysql_manager_error.h"
|
||||
|
||||
|
||||
pthread_handler_t guardian(void *arg)
|
||||
@@ -40,6 +38,37 @@ pthread_handler_t guardian(void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
Guardian_thread::get_instance_state_name(enum_instance_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case NOT_STARTED:
|
||||
return "offline";
|
||||
|
||||
case STARTING:
|
||||
return "starting";
|
||||
|
||||
case STARTED:
|
||||
return "online";
|
||||
|
||||
case JUST_CRASHED:
|
||||
return "failed";
|
||||
|
||||
case CRASHED:
|
||||
return "crashed";
|
||||
|
||||
case CRASHED_AND_ABANDONED:
|
||||
return "abandoned";
|
||||
|
||||
case STOPPING:
|
||||
return "stopping";
|
||||
}
|
||||
|
||||
return NULL; /* just to ignore compiler warning. */
|
||||
}
|
||||
|
||||
|
||||
Guardian_thread::Guardian_thread(Thread_registry &thread_registry_arg,
|
||||
Instance_map *instance_map_arg,
|
||||
uint monitoring_interval_arg) :
|
||||
@@ -89,10 +118,17 @@ void Guardian_thread::process_instance(Instance *instance,
|
||||
if (current_node->state == STOPPING)
|
||||
{
|
||||
/* this brach is executed during shutdown */
|
||||
if (instance->options.shutdown_delay_val)
|
||||
if (instance->options.shutdown_delay)
|
||||
{
|
||||
/*
|
||||
NOTE: it is important to check shutdown_delay here, but use
|
||||
shutdown_delay_val. The idea is that if the option is unset,
|
||||
shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
|
||||
*/
|
||||
waitchild= instance->options.shutdown_delay_val;
|
||||
}
|
||||
|
||||
/* this returns true if and only if an instance was stopped for sure */
|
||||
/* this returns TRUE if and only if an instance was stopped for sure */
|
||||
if (instance->is_crashed())
|
||||
*guarded_instances= list_delete(*guarded_instances, node);
|
||||
else if ( (uint) (current_time - current_node->last_checked) > waitchild)
|
||||
@@ -159,8 +195,12 @@ void Guardian_thread::process_instance(Instance *instance,
|
||||
instance->options.instance_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("guardian: cannot start instance %s. Abandoning attempts "
|
||||
"to (re)start it", instance->options.instance_name);
|
||||
current_node->state= CRASHED_AND_ABANDONED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CRASHED_AND_ABANDONED:
|
||||
break; /* do nothing */
|
||||
@@ -242,7 +282,9 @@ int Guardian_thread::is_stopped()
|
||||
SYNOPSYS
|
||||
Guardian_thread::init()
|
||||
|
||||
NOTE: One should always lock guardian before calling this routine.
|
||||
NOTE: The operation should be invoked with the following locks acquired:
|
||||
- Guardian_thread;
|
||||
- Instance_map;
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
@@ -261,13 +303,12 @@ int Guardian_thread::init()
|
||||
|
||||
while ((instance= iterator.next()))
|
||||
{
|
||||
if (!(instance->options.nonguarded))
|
||||
if (instance->options.nonguarded)
|
||||
continue;
|
||||
|
||||
if (guard(instance, TRUE)) /* do not lock guardian */
|
||||
{
|
||||
instance_map->unlock();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -334,24 +375,14 @@ int Guardian_thread::stop_guard(Instance *instance)
|
||||
LIST *node;
|
||||
|
||||
pthread_mutex_lock(&LOCK_guardian);
|
||||
node= guarded_instances;
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
/*
|
||||
We compare only pointers, as we always use pointers from the
|
||||
instance_map's MEM_ROOT.
|
||||
*/
|
||||
if (((GUARD_NODE *) node->data)->instance == instance)
|
||||
{
|
||||
node= find_instance_node(instance);
|
||||
|
||||
if (node != NULL)
|
||||
guarded_instances= list_delete(guarded_instances, node);
|
||||
|
||||
pthread_mutex_unlock(&LOCK_guardian);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
node= node->next;
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_guardian);
|
||||
|
||||
/* if there is nothing to delete it is also fine */
|
||||
return 0;
|
||||
}
|
||||
@@ -428,3 +459,41 @@ void Guardian_thread::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_guardian);
|
||||
}
|
||||
|
||||
|
||||
LIST *Guardian_thread::find_instance_node(Instance *instance)
|
||||
{
|
||||
LIST *node= guarded_instances;
|
||||
|
||||
while (node != NULL)
|
||||
{
|
||||
/*
|
||||
We compare only pointers, as we always use pointers from the
|
||||
instance_map's MEM_ROOT.
|
||||
*/
|
||||
if (((GUARD_NODE *) node->data)->instance == instance)
|
||||
return node;
|
||||
|
||||
node= node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Guardian_thread::is_active(Instance *instance)
|
||||
{
|
||||
bool guarded;
|
||||
|
||||
lock();
|
||||
|
||||
guarded= find_instance_node(instance) != NULL;
|
||||
|
||||
/* is_running() can take a long time, so let's unlock mutex first. */
|
||||
unlock();
|
||||
|
||||
if (guarded)
|
||||
return true;
|
||||
|
||||
return instance->is_running();
|
||||
}
|
||||
|
@@ -17,11 +17,11 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "thread_registry.h"
|
||||
|
||||
#include <my_sys.h>
|
||||
#include <my_list.h>
|
||||
|
||||
#include "thread_registry.h"
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
#endif
|
||||
@@ -79,6 +79,8 @@ public:
|
||||
time_t last_checked;
|
||||
};
|
||||
|
||||
/* Return client state name. */
|
||||
static const char *get_instance_state_name(enum_instance_state state);
|
||||
|
||||
Guardian_thread(Thread_registry &thread_registry_arg,
|
||||
Instance_map *instance_map_arg,
|
||||
@@ -94,11 +96,28 @@ public:
|
||||
int guard(Instance *instance, bool nolock= FALSE);
|
||||
/* Stop instance protection */
|
||||
int stop_guard(Instance *instance);
|
||||
/* Returns true if guardian thread is stopped */
|
||||
/* Returns TRUE if guardian thread is stopped */
|
||||
int is_stopped();
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
/*
|
||||
Return an internal list node for the given instance if the instance is
|
||||
managed by Guardian. Otherwise, return NULL.
|
||||
|
||||
MT-NOTE: must be called under acquired lock.
|
||||
*/
|
||||
LIST *find_instance_node(Instance *instance);
|
||||
|
||||
/* The operation is used to check if the instance is active or not. */
|
||||
bool is_active(Instance *instance);
|
||||
|
||||
/*
|
||||
Return state of the given instance list node. The pointer must specify
|
||||
a valid list node.
|
||||
*/
|
||||
inline enum_instance_state get_instance_state(LIST *instance_node);
|
||||
|
||||
public:
|
||||
pthread_cond_t COND_guardian;
|
||||
|
||||
@@ -108,6 +127,7 @@ private:
|
||||
/* check instance state and act accordingly */
|
||||
void process_instance(Instance *instance, GUARD_NODE *current_node,
|
||||
LIST **guarded_instances, LIST *elem);
|
||||
|
||||
int stopped;
|
||||
|
||||
private:
|
||||
@@ -115,9 +135,15 @@ private:
|
||||
Thread_info thread_info;
|
||||
LIST *guarded_instances;
|
||||
MEM_ROOT alloc;
|
||||
enum { MEM_ROOT_BLOCK_SIZE= 512 };
|
||||
/* this variable is set to TRUE when we want to stop Guardian thread */
|
||||
bool shutdown_requested;
|
||||
};
|
||||
|
||||
|
||||
inline Guardian_thread::enum_instance_state
|
||||
Guardian_thread::get_instance_state(LIST *instance_node)
|
||||
{
|
||||
return ((GUARD_NODE *) instance_node->data)->state;
|
||||
}
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H */
|
||||
|
@@ -20,18 +20,27 @@
|
||||
|
||||
#include "instance.h"
|
||||
|
||||
#include "mysql_manager_error.h"
|
||||
#include "log.h"
|
||||
#include "instance_map.h"
|
||||
#include "priv.h"
|
||||
#include "portability.h"
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
|
||||
#include <signal.h>
|
||||
#ifndef __WIN__
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <my_sys.h>
|
||||
#include <signal.h>
|
||||
#include <m_string.h>
|
||||
#include <mysql.h>
|
||||
|
||||
#include "guardian.h"
|
||||
#include "instance_map.h"
|
||||
#include "log.h"
|
||||
#include "mysql_manager_error.h"
|
||||
#include "portability.h"
|
||||
#include "priv.h"
|
||||
|
||||
|
||||
const LEX_STRING
|
||||
Instance::DFLT_INSTANCE_NAME= { C_STRING_WITH_SIZE("mysqld") };
|
||||
|
||||
static const char * const INSTANCE_NAME_PREFIX= Instance::DFLT_INSTANCE_NAME.str;
|
||||
static const int INSTANCE_NAME_PREFIX_LEN= Instance::DFLT_INSTANCE_NAME.length;
|
||||
|
||||
|
||||
static void start_and_monitor_instance(Instance_options *old_instance_options,
|
||||
@@ -152,7 +161,7 @@ static int start_process(Instance_options *instance_options,
|
||||
|
||||
switch (*pi) {
|
||||
case 0: /* never happens on QNX */
|
||||
execv(instance_options->mysqld_path, instance_options->argv);
|
||||
execv(instance_options->mysqld_path.str, instance_options->argv);
|
||||
/* exec never returns */
|
||||
exit(1);
|
||||
case -1:
|
||||
@@ -232,9 +241,7 @@ static int start_process(Instance_options *instance_options,
|
||||
static void start_and_monitor_instance(Instance_options *old_instance_options,
|
||||
Instance_map *instance_map)
|
||||
{
|
||||
enum { MAX_INSTANCE_NAME_LEN= 512 };
|
||||
char instance_name_buff[MAX_INSTANCE_NAME_LEN];
|
||||
uint instance_name_len;
|
||||
Instance_name instance_name(&old_instance_options->instance_name);
|
||||
Instance *current_instance;
|
||||
My_process_info process_info;
|
||||
|
||||
@@ -248,11 +255,8 @@ static void start_and_monitor_instance(Instance_options *old_instance_options,
|
||||
Save the instance name in the case if Instance object we
|
||||
are using is destroyed. (E.g. by "FLUSH INSTANCES")
|
||||
*/
|
||||
strmake(instance_name_buff, old_instance_options->instance_name,
|
||||
MAX_INSTANCE_NAME_LEN - 1);
|
||||
instance_name_len= old_instance_options->instance_name_len;
|
||||
|
||||
log_info("starting instance %s", instance_name_buff);
|
||||
log_info("starting instance %s", (const char *) instance_name.get_c_str());
|
||||
|
||||
if (start_process(old_instance_options, &process_info))
|
||||
{
|
||||
@@ -266,15 +270,36 @@ static void start_and_monitor_instance(Instance_options *old_instance_options,
|
||||
/* don't check for return value */
|
||||
wait_process(&process_info);
|
||||
|
||||
current_instance= instance_map->find(instance_name_buff, instance_name_len);
|
||||
instance_map->lock();
|
||||
|
||||
current_instance= instance_map->find(instance_name.get_str());
|
||||
|
||||
if (current_instance)
|
||||
current_instance->set_crash_flag_n_wake_all();
|
||||
|
||||
instance_map->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool Instance::is_name_valid(const LEX_STRING *name)
|
||||
{
|
||||
const char *name_suffix= name->str + INSTANCE_NAME_PREFIX_LEN;
|
||||
|
||||
if (strncmp(name->str, INSTANCE_NAME_PREFIX, INSTANCE_NAME_PREFIX_LEN) != 0)
|
||||
return FALSE;
|
||||
|
||||
return *name_suffix == 0 || my_isdigit(default_charset_info, *name_suffix);
|
||||
}
|
||||
|
||||
|
||||
bool Instance::is_mysqld_compatible_name(const LEX_STRING *name)
|
||||
{
|
||||
return strcmp(name->str, INSTANCE_NAME_PREFIX) == 0;
|
||||
}
|
||||
|
||||
|
||||
Instance_map *Instance::get_map()
|
||||
{
|
||||
return instance_map;
|
||||
@@ -309,11 +334,11 @@ int Instance::start()
|
||||
{
|
||||
/* clear crash flag */
|
||||
pthread_mutex_lock(&LOCK_instance);
|
||||
crashed= 0;
|
||||
crashed= FALSE;
|
||||
pthread_mutex_unlock(&LOCK_instance);
|
||||
|
||||
|
||||
if (!is_running())
|
||||
if (configured && !is_running())
|
||||
{
|
||||
remove_pid();
|
||||
|
||||
@@ -339,8 +364,8 @@ int Instance::start()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the instance is started already */
|
||||
return ER_INSTANCE_ALREADY_STARTED;
|
||||
/* The instance is started already or misconfigured. */
|
||||
return configured ? ER_INSTANCE_ALREADY_STARTED : ER_INSTANCE_MISCONFIGURED;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -363,7 +388,7 @@ void Instance::set_crash_flag_n_wake_all()
|
||||
{
|
||||
/* set instance state to crashed */
|
||||
pthread_mutex_lock(&LOCK_instance);
|
||||
crashed= 1;
|
||||
crashed= TRUE;
|
||||
pthread_mutex_unlock(&LOCK_instance);
|
||||
|
||||
/*
|
||||
@@ -378,7 +403,7 @@ void Instance::set_crash_flag_n_wake_all()
|
||||
|
||||
|
||||
|
||||
Instance::Instance(): crashed(0)
|
||||
Instance::Instance(): crashed(FALSE), configured(FALSE)
|
||||
{
|
||||
pthread_mutex_init(&LOCK_instance, 0);
|
||||
pthread_cond_init(&COND_instance_stopped, 0);
|
||||
@@ -392,9 +417,9 @@ Instance::~Instance()
|
||||
}
|
||||
|
||||
|
||||
int Instance::is_crashed()
|
||||
bool Instance::is_crashed()
|
||||
{
|
||||
int val;
|
||||
bool val;
|
||||
pthread_mutex_lock(&LOCK_instance);
|
||||
val= crashed;
|
||||
pthread_mutex_unlock(&LOCK_instance);
|
||||
@@ -413,10 +438,17 @@ bool Instance::is_running()
|
||||
bool return_val;
|
||||
|
||||
if (options.mysqld_port)
|
||||
{
|
||||
/*
|
||||
NOTE: it is important to check mysqld_port here, but use
|
||||
mysqld_port_val. The idea is that if the option is unset, mysqld_port
|
||||
will be NULL, but mysqld_port_val will not be reset.
|
||||
*/
|
||||
port= options.mysqld_port_val;
|
||||
}
|
||||
|
||||
if (options.mysqld_socket)
|
||||
socket= strchr(options.mysqld_socket, '=') + 1;
|
||||
socket= options.mysqld_socket;
|
||||
|
||||
/* no port was specified => instance falled back to default value */
|
||||
if (!options.mysqld_port && !options.mysqld_socket)
|
||||
@@ -469,8 +501,15 @@ int Instance::stop()
|
||||
struct timespec timeout;
|
||||
uint waitchild= (uint) DEFAULT_SHUTDOWN_DELAY;
|
||||
|
||||
if (options.shutdown_delay_val)
|
||||
if (options.shutdown_delay)
|
||||
{
|
||||
/*
|
||||
NOTE: it is important to check shutdown_delay here, but use
|
||||
shutdown_delay_val. The idea is that if the option is unset,
|
||||
shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
|
||||
*/
|
||||
waitchild= options.shutdown_delay_val;
|
||||
}
|
||||
|
||||
kill_instance(SIGTERM);
|
||||
/* sleep on condition to wait for SIGCHLD */
|
||||
@@ -588,20 +627,33 @@ void Instance::kill_instance(int signum)
|
||||
}
|
||||
|
||||
/*
|
||||
We execute this function to initialize instance parameters.
|
||||
Return value: 0 - ok. 1 - unable to init DYNAMIC_ARRAY.
|
||||
Initialize instance parameters.
|
||||
|
||||
SYNOPSYS
|
||||
Instance::init()
|
||||
name_arg name of the instance
|
||||
|
||||
RETURN:
|
||||
0 ok
|
||||
!0 error
|
||||
*/
|
||||
|
||||
int Instance::init(const char *name_arg)
|
||||
int Instance::init(const LEX_STRING *name_arg)
|
||||
{
|
||||
mysqld_compatible= is_mysqld_compatible_name(name_arg);
|
||||
|
||||
return options.init(name_arg);
|
||||
}
|
||||
|
||||
|
||||
int Instance::complete_initialization(Instance_map *instance_map_arg,
|
||||
const char *mysqld_path,
|
||||
uint instance_type)
|
||||
const char *mysqld_path)
|
||||
{
|
||||
instance_map= instance_map_arg;
|
||||
return options.complete_initialization(mysqld_path, instance_type);
|
||||
configured= !options.complete_initialization(mysqld_path);
|
||||
return 0;
|
||||
/*
|
||||
TODO: return actual status (from
|
||||
Instance_options::complete_initialization()) here.
|
||||
*/
|
||||
}
|
||||
|
@@ -17,7 +17,10 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
|
||||
#include "instance_options.h"
|
||||
#include "priv.h"
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
@@ -25,31 +28,120 @@
|
||||
|
||||
class Instance_map;
|
||||
|
||||
|
||||
/*
|
||||
Instance_name -- the class represents instance name -- a string of length
|
||||
less than MAX_INSTANCE_NAME_SIZE.
|
||||
|
||||
Generally, this is just a string with self-memory-management and should be
|
||||
eliminated in the future.
|
||||
*/
|
||||
|
||||
class Instance_name
|
||||
{
|
||||
public:
|
||||
Instance_name(const LEX_STRING *name);
|
||||
|
||||
public:
|
||||
inline const LEX_STRING *get_str() const
|
||||
{
|
||||
return &str;
|
||||
}
|
||||
|
||||
inline const char *get_c_str() const
|
||||
{
|
||||
return str.str;
|
||||
}
|
||||
|
||||
inline uint get_length() const
|
||||
{
|
||||
return str.length;
|
||||
}
|
||||
|
||||
private:
|
||||
LEX_STRING str;
|
||||
char str_buffer[MAX_INSTANCE_NAME_SIZE];
|
||||
};
|
||||
|
||||
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
/*
|
||||
The following two constants defines name of the default mysqld-instance
|
||||
("mysqld").
|
||||
*/
|
||||
static const LEX_STRING DFLT_INSTANCE_NAME;
|
||||
|
||||
public:
|
||||
/*
|
||||
The operation is intended to check whether string is a well-formed
|
||||
instance name or not.
|
||||
*/
|
||||
static bool is_name_valid(const LEX_STRING *name);
|
||||
|
||||
/*
|
||||
The operation is intended to check if the given instance name is
|
||||
mysqld-compatible or not.
|
||||
*/
|
||||
static bool is_mysqld_compatible_name(const LEX_STRING *name);
|
||||
|
||||
public:
|
||||
Instance();
|
||||
|
||||
~Instance();
|
||||
int init(const char *name);
|
||||
int init(const LEX_STRING *name_arg);
|
||||
int complete_initialization(Instance_map *instance_map_arg,
|
||||
const char *mysqld_path, uint instance_type);
|
||||
const char *mysqld_path);
|
||||
|
||||
bool is_running();
|
||||
int start();
|
||||
int stop();
|
||||
/* send a signal to the instance */
|
||||
void kill_instance(int signo);
|
||||
int is_crashed();
|
||||
bool is_crashed();
|
||||
void set_crash_flag_n_wake_all();
|
||||
Instance_map *get_map();
|
||||
|
||||
/*
|
||||
The operation is intended to check if the instance is mysqld-compatible
|
||||
or not.
|
||||
*/
|
||||
inline bool is_mysqld_compatible() const;
|
||||
|
||||
/*
|
||||
The operation is intended to check if the instance is configured properly
|
||||
or not. Misconfigured instances are not managed.
|
||||
*/
|
||||
inline bool is_configured() const;
|
||||
|
||||
inline const LEX_STRING *get_name() const;
|
||||
|
||||
public:
|
||||
enum { DEFAULT_SHUTDOWN_DELAY= 35 };
|
||||
Instance_options options;
|
||||
|
||||
private:
|
||||
int crashed;
|
||||
/* This attributes is a flag, specifies if the instance has been crashed. */
|
||||
bool crashed;
|
||||
|
||||
/*
|
||||
This attribute specifies if the instance is configured properly or not.
|
||||
Misconfigured instances are not managed.
|
||||
*/
|
||||
bool configured;
|
||||
|
||||
/*
|
||||
This attribute specifies whether the instance is mysqld-compatible or not.
|
||||
Mysqld-compatible instances can contain only mysqld-specific options.
|
||||
At the moment an instance is mysqld-compatible if its name is "mysqld".
|
||||
|
||||
The idea is that [mysqld] section should contain only mysqld-specific
|
||||
options (no Instance Manager-specific options) to be readable by mysqld
|
||||
program.
|
||||
*/
|
||||
bool mysqld_compatible;
|
||||
|
||||
/*
|
||||
Mutex protecting the instance. Currently we use it to avoid the
|
||||
double start of the instance. This happens when the instance is starting
|
||||
@@ -66,4 +158,22 @@ private:
|
||||
void remove_pid();
|
||||
};
|
||||
|
||||
|
||||
inline bool Instance::is_mysqld_compatible() const
|
||||
{
|
||||
return mysqld_compatible;
|
||||
}
|
||||
|
||||
|
||||
inline bool Instance::is_configured() const
|
||||
{
|
||||
return configured;
|
||||
}
|
||||
|
||||
|
||||
inline const LEX_STRING *Instance::get_name() const
|
||||
{
|
||||
return &options.instance_name;
|
||||
}
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H */
|
||||
|
@@ -20,14 +20,19 @@
|
||||
|
||||
#include "instance_map.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include "instance.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
#include <mysql_com.h>
|
||||
#include <m_string.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "guardian.h"
|
||||
#include "instance.h"
|
||||
#include "log.h"
|
||||
#include "manager.h"
|
||||
#include "mysqld_error.h"
|
||||
#include "mysql_manager_error.h"
|
||||
#include "options.h"
|
||||
#include "priv.h"
|
||||
|
||||
/*
|
||||
Note: As we are going to suppost different types of connections,
|
||||
@@ -45,8 +50,8 @@ static byte* get_instance_key(const byte* u, uint* len,
|
||||
my_bool __attribute__((unused)) t)
|
||||
{
|
||||
const Instance *instance= (const Instance *) u;
|
||||
*len= instance->options.instance_name_len;
|
||||
return (byte *) instance->options.instance_name;
|
||||
*len= instance->options.instance_name.length;
|
||||
return (byte *) instance->options.instance_name.str;
|
||||
}
|
||||
|
||||
static void delete_instance(void *u)
|
||||
@@ -79,15 +84,59 @@ static void delete_instance(void *u)
|
||||
|
||||
static int process_option(void *ctx, const char *group, const char *option)
|
||||
{
|
||||
Instance_map *map= NULL;
|
||||
Instance_map *map= (Instance_map*) ctx;
|
||||
LEX_STRING group_str;
|
||||
|
||||
map = (Instance_map*) ctx;
|
||||
return map->process_one_option(group, option);
|
||||
group_str.str= (char *) group;
|
||||
group_str.length= strlen(group);
|
||||
|
||||
return map->process_one_option(&group_str, option);
|
||||
}
|
||||
|
||||
C_MODE_END
|
||||
|
||||
|
||||
/*
|
||||
Parse option string.
|
||||
|
||||
SYNOPSIS
|
||||
parse_option()
|
||||
option_str [IN] option string (e.g. "--name=value")
|
||||
option_name_buf [OUT] parsed name of the option.
|
||||
Must be of (MAX_OPTION_LEN + 1) size.
|
||||
option_value_buf [OUT] parsed value of the option.
|
||||
Must be of (MAX_OPTION_LEN + 1) size.
|
||||
|
||||
DESCRIPTION
|
||||
This is an auxiliary function and should not be used externally. It is
|
||||
intended to parse whole option string into option name and option value.
|
||||
*/
|
||||
|
||||
static void parse_option(const char *option_str,
|
||||
char *option_name_buf,
|
||||
char *option_value_buf)
|
||||
{
|
||||
const char *eq_pos;
|
||||
const char *ptr= option_str;
|
||||
|
||||
while (*ptr == '-')
|
||||
++ptr;
|
||||
|
||||
strmake(option_name_buf, ptr, MAX_OPTION_LEN + 1);
|
||||
|
||||
eq_pos= strchr(ptr, '=');
|
||||
if (eq_pos)
|
||||
{
|
||||
option_name_buf[eq_pos - ptr]= 0;
|
||||
strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
option_value_buf[0]= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Process one option from the configuration file.
|
||||
|
||||
@@ -103,34 +152,64 @@ C_MODE_END
|
||||
of the instance map object.
|
||||
*/
|
||||
|
||||
int Instance_map::process_one_option(const char *group, const char *option)
|
||||
int Instance_map::process_one_option(const LEX_STRING *group,
|
||||
const char *option)
|
||||
{
|
||||
Instance *instance= NULL;
|
||||
static const char prefix[]= { 'm', 'y', 's', 'q', 'l', 'd' };
|
||||
|
||||
if (strncmp(group, prefix, sizeof prefix) == 0 &&
|
||||
((my_isdigit(default_charset_info, group[sizeof prefix]))
|
||||
|| group[sizeof(prefix)] == '\0'))
|
||||
if (!Instance::is_name_valid(group))
|
||||
{
|
||||
if (!(instance= (Instance *) hash_search(&hash, (byte *) group,
|
||||
strlen(group))))
|
||||
{
|
||||
if (!(instance= new Instance))
|
||||
goto err;
|
||||
if (instance->init(group) || my_hash_insert(&hash, (byte *) instance))
|
||||
goto err_instance;
|
||||
/*
|
||||
Current section name is not a valid instance name.
|
||||
We should skip it w/o error.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (instance->options.add_option(option))
|
||||
goto err; /* the instance'll be deleted when we destroy the map */
|
||||
if (!(instance= (Instance *) hash_search(&hash, (byte *) group->str,
|
||||
group->length)))
|
||||
{
|
||||
if (!(instance= new Instance()))
|
||||
return 1;
|
||||
|
||||
if (instance->init(group) || add_instance(instance))
|
||||
{
|
||||
delete instance;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (instance->is_mysqld_compatible())
|
||||
log_info("Warning: instance name '%s' is mysqld-compatible.",
|
||||
(const char *) group->str);
|
||||
|
||||
log_info("mysqld instance '%s' has been added successfully.",
|
||||
(const char *) group->str);
|
||||
}
|
||||
|
||||
if (option)
|
||||
{
|
||||
char option_name[MAX_OPTION_LEN + 1];
|
||||
char option_value[MAX_OPTION_LEN + 1];
|
||||
|
||||
parse_option(option, option_name, option_value);
|
||||
|
||||
if (instance->is_mysqld_compatible() &&
|
||||
Instance_options::is_option_im_specific(option_name))
|
||||
{
|
||||
log_info("Warning: configuration of mysqld-compatible instance '%s' "
|
||||
"contains IM-specific option '%s'. "
|
||||
"This breaks backward compatibility for the configuration file.",
|
||||
(const char *) group->str,
|
||||
(const char *) option_name);
|
||||
}
|
||||
|
||||
Named_value option(option_name, option_value);
|
||||
|
||||
if (instance->options.set_option(&option))
|
||||
return 1; /* the instance'll be deleted when we destroy the map */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_instance:
|
||||
delete instance;
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +260,7 @@ void Instance_map::unlock()
|
||||
- pass on the new map to the guardian thread: it will start
|
||||
all instances that are marked `guarded' and not yet started.
|
||||
Note, as the check whether an instance is started is currently
|
||||
very simple (returns true if there is a MySQL server running
|
||||
very simple (returns TRUE if there is a MySQL server running
|
||||
at the given port), this function has some peculiar
|
||||
side-effects:
|
||||
* if the port number of a running instance was changed, the
|
||||
@@ -194,9 +273,9 @@ void Instance_map::unlock()
|
||||
In order to avoid such side effects one should never call
|
||||
FLUSH INSTANCES without prior stop of all running instances.
|
||||
|
||||
TODO
|
||||
FLUSH INSTANCES should return an error if it's called
|
||||
while there is a running instance.
|
||||
NOTE: The operation should be invoked with the following locks acquired:
|
||||
- Guardian_thread;
|
||||
- Instance_map;
|
||||
*/
|
||||
|
||||
int Instance_map::flush_instances()
|
||||
@@ -209,67 +288,169 @@ int Instance_map::flush_instances()
|
||||
guardian (2) reload the instance map (3) reinitialize the guardian
|
||||
with new instances.
|
||||
*/
|
||||
guardian->lock();
|
||||
pthread_mutex_lock(&LOCK_instance_map);
|
||||
hash_free(&hash);
|
||||
hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||
get_instance_key, delete_instance, 0);
|
||||
|
||||
rc= load();
|
||||
guardian->init();
|
||||
pthread_mutex_unlock(&LOCK_instance_map);
|
||||
guardian->unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Instance *
|
||||
Instance_map::find(const char *name, uint name_len)
|
||||
bool Instance_map::is_there_active_instance()
|
||||
{
|
||||
Instance *instance;
|
||||
pthread_mutex_lock(&LOCK_instance_map);
|
||||
instance= (Instance *) hash_search(&hash, (byte *) name, name_len);
|
||||
pthread_mutex_unlock(&LOCK_instance_map);
|
||||
return instance;
|
||||
Iterator iterator(this);
|
||||
|
||||
while ((instance= iterator.next()))
|
||||
{
|
||||
if (guardian->find_instance_node(instance) != NULL ||
|
||||
instance->is_running())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int Instance_map::complete_initialization()
|
||||
int Instance_map::add_instance(Instance *instance)
|
||||
{
|
||||
Instance *instance;
|
||||
uint i= 0;
|
||||
return my_hash_insert(&hash, (byte *) instance);
|
||||
}
|
||||
|
||||
|
||||
if (hash.records == 0) /* no instances found */
|
||||
int Instance_map::remove_instance(Instance *instance)
|
||||
{
|
||||
return hash_delete(&hash, (byte *) instance);
|
||||
}
|
||||
|
||||
|
||||
int Instance_map::create_instance(const LEX_STRING *instance_name,
|
||||
const Named_value_arr *options)
|
||||
{
|
||||
Instance *instance= new Instance();
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
if ((instance= new Instance) == 0)
|
||||
goto err;
|
||||
|
||||
if (instance->init("mysqld") || my_hash_insert(&hash, (byte *) instance))
|
||||
goto err_instance;
|
||||
|
||||
/*
|
||||
After an instance have been added to the instance_map,
|
||||
hash_free should handle it's deletion => goto err, not
|
||||
err_instance.
|
||||
*/
|
||||
if (instance->complete_initialization(this, mysqld_path,
|
||||
DEFAULT_SINGLE_INSTANCE))
|
||||
goto err;
|
||||
log_error("Error: can not initialize (name: '%s').",
|
||||
(const char *) instance_name->str);
|
||||
return ER_OUT_OF_RESOURCES;
|
||||
}
|
||||
else
|
||||
while (i < hash.records)
|
||||
|
||||
if (instance->init(instance_name))
|
||||
{
|
||||
instance= (Instance *) hash_element(&hash, i);
|
||||
if (instance->complete_initialization(this, mysqld_path, USUAL_INSTANCE))
|
||||
goto err;
|
||||
i++;
|
||||
log_error("Error: can not initialize (name: '%s').",
|
||||
(const char *) instance_name->str);
|
||||
delete instance;
|
||||
return ER_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (int i= 0; options && i < options->get_size(); ++i)
|
||||
{
|
||||
Named_value option= options->get_element(i);
|
||||
|
||||
if (instance->is_mysqld_compatible() &&
|
||||
Instance_options::is_option_im_specific(option.get_name()))
|
||||
{
|
||||
log_error("Error: IM-option (%s) can not be used "
|
||||
"in configuration of mysqld-compatible instance (%s).",
|
||||
(const char *) option.get_name(),
|
||||
(const char *) instance_name->str);
|
||||
delete instance;
|
||||
return ER_INCOMPATIBLE_OPTION;
|
||||
}
|
||||
|
||||
instance->options.set_option(&option);
|
||||
}
|
||||
|
||||
if (instance->is_mysqld_compatible())
|
||||
log_info("Warning: instance name '%s' is mysqld-compatible.",
|
||||
(const char *) instance_name->str);
|
||||
|
||||
if (instance->complete_initialization(this, mysqld_path))
|
||||
{
|
||||
log_error("Error: can not complete initialization of instance (name: '%s').",
|
||||
(const char *) instance_name->str);
|
||||
delete instance;
|
||||
return ER_OUT_OF_RESOURCES;
|
||||
/* TODO: return more appropriate error code in this case. */
|
||||
}
|
||||
|
||||
if (add_instance(instance))
|
||||
{
|
||||
log_error("Error: can not register instance (name: '%s').",
|
||||
(const char *) instance_name->str);
|
||||
delete instance;
|
||||
return ER_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_instance:
|
||||
delete instance;
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Instance * Instance_map::find(const LEX_STRING *name)
|
||||
{
|
||||
return (Instance *) hash_search(&hash, (byte *) name->str, name->length);
|
||||
}
|
||||
|
||||
|
||||
bool Instance_map::complete_initialization()
|
||||
{
|
||||
bool mysqld_found;
|
||||
|
||||
/* Complete initialization of all registered instances. */
|
||||
|
||||
for (uint i= 0; i < hash.records; ++i)
|
||||
{
|
||||
Instance *instance= (Instance *) hash_element(&hash, i);
|
||||
|
||||
if (instance->complete_initialization(this, mysqld_path))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* That's all if we are runnning in an ordinary mode. */
|
||||
|
||||
if (!Options::Main::mysqld_safe_compatible)
|
||||
return FALSE;
|
||||
|
||||
/* In mysqld-compatible mode we must ensure that there 'mysqld' instance. */
|
||||
|
||||
mysqld_found= find(&Instance::DFLT_INSTANCE_NAME) != NULL;
|
||||
|
||||
if (mysqld_found)
|
||||
return FALSE;
|
||||
|
||||
if (create_instance(&Instance::DFLT_INSTANCE_NAME, NULL))
|
||||
{
|
||||
log_error("Error: could not create default instance.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (create_instance_in_file(&Instance::DFLT_INSTANCE_NAME, NULL))
|
||||
{
|
||||
case 0:
|
||||
case ER_CONF_FILE_DOES_NOT_EXIST:
|
||||
/*
|
||||
Continue if the instance has been added to the config file
|
||||
successfully, or the config file just does not exist.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Error: could not add default instance to the config file.");
|
||||
|
||||
Instance *instance= find(&Instance::DFLT_INSTANCE_NAME);
|
||||
|
||||
if (instance)
|
||||
remove_instance(instance); /* instance is deleted here. */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,10 +478,10 @@ int Instance_map::load()
|
||||
name and start looking for files named "my.cnf.cnf" in all
|
||||
default dirs. Which is not what we want.
|
||||
*/
|
||||
if (Options::is_forced_default_file)
|
||||
if (Options::Main::is_forced_default_file)
|
||||
{
|
||||
snprintf(defaults_file_arg, FN_REFLEN, "--defaults-file=%s",
|
||||
Options::config_file);
|
||||
Options::Main::config_file);
|
||||
|
||||
argv_options[1]= defaults_file_arg;
|
||||
argv_options[2]= '\0';
|
||||
@@ -314,15 +495,12 @@ int Instance_map::load()
|
||||
If the routine failed, we'll simply fallback to defaults in
|
||||
complete_initialization().
|
||||
*/
|
||||
if (my_search_option_files(Options::config_file, &argc,
|
||||
if (my_search_option_files(Options::Main::config_file, &argc,
|
||||
(char ***) &argv, &args_used,
|
||||
process_option, (void*) this))
|
||||
log_info("Falling back to compiled-in defaults");
|
||||
|
||||
if (complete_initialization())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return complete_initialization();
|
||||
}
|
||||
|
||||
|
||||
@@ -343,3 +521,105 @@ Instance *Instance_map::Iterator::next()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *Instance_map::get_instance_state_name(Instance *instance)
|
||||
{
|
||||
LIST *instance_node;
|
||||
|
||||
if (!instance->is_configured())
|
||||
return "misconfigured";
|
||||
|
||||
if ((instance_node= guardian->find_instance_node(instance)) != NULL)
|
||||
{
|
||||
/* The instance is managed by Guardian: we can report precise state. */
|
||||
|
||||
return Guardian_thread::get_instance_state_name(
|
||||
guardian->get_instance_state(instance_node));
|
||||
}
|
||||
|
||||
/* The instance is not managed by Guardian: we can report status only. */
|
||||
|
||||
return instance->is_running() ? "online" : "offline";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a new configuration section for mysqld-instance in the config file.
|
||||
|
||||
SYNOPSYS
|
||||
create_instance_in_file()
|
||||
instance_name mysqld-instance name
|
||||
options options for the new mysqld-instance
|
||||
|
||||
RETURN
|
||||
0 On success
|
||||
ER_CONF_FILE_DOES_NOT_EXIST If config file does not exist
|
||||
ER_ACCESS_OPTION_FILE If config file is not writable or some I/O
|
||||
error ocurred during writing configuration
|
||||
*/
|
||||
|
||||
int create_instance_in_file(const LEX_STRING *instance_name,
|
||||
const Named_value_arr *options)
|
||||
{
|
||||
File cnf_file;
|
||||
|
||||
if (my_access(Options::Main::config_file, W_OK))
|
||||
{
|
||||
log_error("Error: configuration file (%s) does not exist.",
|
||||
(const char *) Options::Main::config_file);
|
||||
return ER_CONF_FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
cnf_file= my_open(Options::Main::config_file, O_WRONLY | O_APPEND, MYF(0));
|
||||
|
||||
if (cnf_file <= 0)
|
||||
{
|
||||
log_error("Error: can not open configuration file (%s): %s.",
|
||||
(const char *) Options::Main::config_file,
|
||||
(const char *) strerror(errno));
|
||||
return ER_ACCESS_OPTION_FILE;
|
||||
}
|
||||
|
||||
if (my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)) ||
|
||||
my_write(cnf_file, (byte*)"[", 1, MYF(MY_NABP)) ||
|
||||
my_write(cnf_file, (byte*)instance_name->str, instance_name->length,
|
||||
MYF(MY_NABP)) ||
|
||||
my_write(cnf_file, (byte*)"]", 1, MYF(MY_NABP)) ||
|
||||
my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
|
||||
{
|
||||
log_error("Error: can not write to configuration file (%s): %s.",
|
||||
(const char *) Options::Main::config_file,
|
||||
(const char *) strerror(errno));
|
||||
my_close(cnf_file, MYF(0));
|
||||
return ER_ACCESS_OPTION_FILE;
|
||||
}
|
||||
|
||||
for (int i= 0; options && i < options->get_size(); ++i)
|
||||
{
|
||||
char option_str[MAX_OPTION_STR_LEN];
|
||||
char *ptr;
|
||||
int option_str_len;
|
||||
Named_value option= options->get_element(i);
|
||||
|
||||
ptr= strxnmov(option_str, MAX_OPTION_LEN + 1, option.get_name(), NullS);
|
||||
|
||||
if (option.get_value()[0])
|
||||
ptr= strxnmov(ptr, MAX_OPTION_LEN + 2, "=", option.get_value(), NullS);
|
||||
|
||||
option_str_len= ptr - option_str;
|
||||
|
||||
if (my_write(cnf_file, (byte*)option_str, option_str_len, MYF(MY_NABP)) ||
|
||||
my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
|
||||
{
|
||||
log_error("Error: can not write to configuration file (%s): %s.",
|
||||
(const char *) Options::Main::config_file,
|
||||
(const char *) strerror(errno));
|
||||
my_close(cnf_file, MYF(0));
|
||||
return ER_ACCESS_OPTION_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
my_close(cnf_file, MYF(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -17,21 +17,24 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
#include "protocol.h"
|
||||
#include "guardian.h"
|
||||
|
||||
#include <my_sys.h>
|
||||
#include <m_string.h>
|
||||
#include <hash.h>
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class Guardian_thread;
|
||||
class Instance;
|
||||
class Named_value_arr;
|
||||
|
||||
extern int load_all_groups(char ***groups, const char *filename);
|
||||
extern void free_groups(char **groups);
|
||||
|
||||
extern int create_instance_in_file(const LEX_STRING *instance_name,
|
||||
const Named_value_arr *options);
|
||||
|
||||
|
||||
/*
|
||||
Instance_map - stores all existing instances
|
||||
@@ -56,22 +59,64 @@ public:
|
||||
};
|
||||
friend class Iterator;
|
||||
public:
|
||||
/* returns a pointer to the instance or NULL, if there is no such instance */
|
||||
Instance *find(const char *name, uint name_len);
|
||||
/*
|
||||
Return a pointer to the instance or NULL, if there is no such instance.
|
||||
MT-NOTE: must be called under acquired lock.
|
||||
*/
|
||||
Instance *find(const LEX_STRING *name);
|
||||
|
||||
/* Clear the configuration cache and reload the configuration file. */
|
||||
int flush_instances();
|
||||
|
||||
/* The operation is used to check if there is an active instance or not. */
|
||||
bool is_there_active_instance();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
int init();
|
||||
|
||||
/*
|
||||
Process a given option and assign it to appropricate instance. This is
|
||||
required for the option handler, passed to my_search_option_files().
|
||||
*/
|
||||
int process_one_option(const char *group, const char *option);
|
||||
int process_one_option(const LEX_STRING *group, const char *option);
|
||||
|
||||
/*
|
||||
Add an instance into the internal hash.
|
||||
|
||||
MT-NOTE: the operation must be called under acquired lock.
|
||||
*/
|
||||
int add_instance(Instance *instance);
|
||||
|
||||
/*
|
||||
Remove instance from the internal hash.
|
||||
|
||||
MT-NOTE: the operation must be called under acquired lock.
|
||||
*/
|
||||
int remove_instance(Instance *instance);
|
||||
|
||||
/*
|
||||
Create a new instance and register it in the internal hash.
|
||||
|
||||
MT-NOTE: the operation must be called under acquired lock.
|
||||
*/
|
||||
int create_instance(const LEX_STRING *instance_name,
|
||||
const Named_value_arr *options);
|
||||
|
||||
Instance_map(const char *default_mysqld_path_arg);
|
||||
~Instance_map();
|
||||
|
||||
/*
|
||||
Retrieve client state name of the given instance.
|
||||
|
||||
MT-NOTE: the options must be called under acquired locks of the following
|
||||
objects:
|
||||
- Instance_map;
|
||||
- Guardian_thread;
|
||||
*/
|
||||
const char *get_instance_state_name(Instance *instance);
|
||||
|
||||
public:
|
||||
const char *mysqld_path;
|
||||
Guardian_thread *guardian;
|
||||
@@ -80,7 +125,7 @@ private:
|
||||
/* loads options from config files */
|
||||
int load();
|
||||
/* inits instances argv's after all options have been loaded */
|
||||
int complete_initialization();
|
||||
bool complete_initialization();
|
||||
private:
|
||||
enum { START_HASH_SIZE = 16 };
|
||||
pthread_mutex_t LOCK_instance_map;
|
||||
|
@@ -20,28 +20,24 @@
|
||||
|
||||
#include "instance_options.h"
|
||||
|
||||
#include "parse_output.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <signal.h>
|
||||
#include <m_string.h>
|
||||
|
||||
#ifdef __WIN__
|
||||
#define NEWLINE_LEN 2
|
||||
#else
|
||||
#define NEWLINE_LEN 1
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "instance.h"
|
||||
#include "log.h"
|
||||
#include "parse_output.h"
|
||||
#include "priv.h"
|
||||
|
||||
|
||||
/* Create "mysqld ..." command in the buffer */
|
||||
|
||||
static inline int create_mysqld_command(Buffer *buf,
|
||||
const char *mysqld_path_str,
|
||||
uint mysqld_path_len,
|
||||
const char *option,
|
||||
uint option_len)
|
||||
const LEX_STRING *mysqld_path,
|
||||
const LEX_STRING *option)
|
||||
{
|
||||
int position= 0;
|
||||
|
||||
@@ -50,13 +46,13 @@ static inline int create_mysqld_command(Buffer *buf,
|
||||
#ifdef __WIN__
|
||||
buf->append(position++, "\"", 1);
|
||||
#endif
|
||||
buf->append(position, mysqld_path_str, mysqld_path_len);
|
||||
position+= mysqld_path_len;
|
||||
buf->append(position, mysqld_path->str, mysqld_path->length);
|
||||
position+= mysqld_path->length;
|
||||
#ifdef __WIN__
|
||||
buf->append(position++, "\"", 1);
|
||||
#endif
|
||||
/* here the '\0' character is copied from the option string */
|
||||
buf->append(position, option, option_len);
|
||||
buf->append(position, option->str, option->length + 1);
|
||||
|
||||
return buf->is_error();
|
||||
}
|
||||
@@ -64,6 +60,42 @@ static inline int create_mysqld_command(Buffer *buf,
|
||||
}
|
||||
|
||||
|
||||
bool Instance_options::is_option_im_specific(const char *option_name)
|
||||
{
|
||||
static const char *IM_SPECIFIC_OPTIONS[] =
|
||||
{
|
||||
"nonguarded",
|
||||
"mysqld-path",
|
||||
"shutdown-delay",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i= 0; IM_SPECIFIC_OPTIONS[i]; ++i)
|
||||
{
|
||||
if (!strcmp(option_name, IM_SPECIFIC_OPTIONS[i]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
Instance_options::Instance_options()
|
||||
:mysqld_version(NULL), mysqld_socket(NULL), mysqld_datadir(NULL),
|
||||
mysqld_pid_file(NULL), mysqld_port(NULL), mysqld_port_val(0),
|
||||
nonguarded(NULL), shutdown_delay(NULL), shutdown_delay_val(0),
|
||||
filled_default_options(0)
|
||||
{
|
||||
mysqld_path.str= NULL;
|
||||
mysqld_path.length= 0;
|
||||
|
||||
mysqld_real_path.str= NULL;
|
||||
mysqld_real_path.length= 0;
|
||||
|
||||
memset(logs, 0, sizeof(logs));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get compiled-in value of default_option
|
||||
|
||||
@@ -87,13 +119,13 @@ int Instance_options::get_default_option(char *result, size_t result_len,
|
||||
const char *option_name)
|
||||
{
|
||||
int rc= 1;
|
||||
char verbose_option[]= " --no-defaults --verbose --help";
|
||||
LEX_STRING verbose_option=
|
||||
{ C_STRING_WITH_SIZE(" --no-defaults --verbose --help") };
|
||||
|
||||
/* reserve space fot the path + option + final '\0' */
|
||||
Buffer cmd(mysqld_path_len + sizeof(verbose_option));
|
||||
/* reserve space for the path + option + final '\0' */
|
||||
Buffer cmd(mysqld_path.length + verbose_option.length + 1);
|
||||
|
||||
if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len,
|
||||
verbose_option, sizeof(verbose_option)))
|
||||
if (create_mysqld_command(&cmd, &mysqld_path, &verbose_option))
|
||||
goto err;
|
||||
|
||||
/* +2 eats first "--" from the option string (E.g. "--datadir") */
|
||||
@@ -121,21 +153,19 @@ err:
|
||||
|
||||
int Instance_options::fill_instance_version()
|
||||
{
|
||||
enum { MAX_VERSION_STRING_LENGTH= 160 };
|
||||
char result[MAX_VERSION_STRING_LENGTH];
|
||||
char version_option[]= " --no-defaults --version";
|
||||
char result[MAX_VERSION_LENGTH];
|
||||
LEX_STRING version_option=
|
||||
{ C_STRING_WITH_SIZE(" --no-defaults --version") };
|
||||
int rc= 1;
|
||||
Buffer cmd(mysqld_path_len + sizeof(version_option));
|
||||
Buffer cmd(mysqld_path.length + version_option.length + 1);
|
||||
|
||||
if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len,
|
||||
version_option, sizeof(version_option)))
|
||||
if (create_mysqld_command(&cmd, &mysqld_path, &version_option))
|
||||
goto err;
|
||||
|
||||
bzero(result, MAX_VERSION_STRING_LENGTH);
|
||||
bzero(result, MAX_VERSION_LENGTH);
|
||||
|
||||
rc= parse_output_and_get_value(cmd.buffer, "Ver",
|
||||
result, MAX_VERSION_STRING_LENGTH,
|
||||
GET_LINE);
|
||||
rc= parse_output_and_get_value(cmd.buffer, "Ver", result,
|
||||
MAX_VERSION_LENGTH, GET_LINE);
|
||||
|
||||
if (*result != '\0')
|
||||
{
|
||||
@@ -146,6 +176,7 @@ int Instance_options::fill_instance_version()
|
||||
start= result;
|
||||
while (my_isspace(default_charset_info, *start))
|
||||
++start;
|
||||
|
||||
mysqld_version= strdup_root(&alloc, start);
|
||||
}
|
||||
err:
|
||||
@@ -178,12 +209,12 @@ err:
|
||||
int Instance_options::fill_mysqld_real_path()
|
||||
{
|
||||
char result[FN_REFLEN];
|
||||
char help_option[]= " --no-defaults --help";
|
||||
LEX_STRING help_option=
|
||||
{ C_STRING_WITH_SIZE(" --no-defaults --help") };
|
||||
int rc= 1;
|
||||
Buffer cmd(mysqld_path_len + sizeof(help_option));
|
||||
Buffer cmd(mysqld_path.length + help_option.length);
|
||||
|
||||
if (create_mysqld_command(&cmd, mysqld_path, mysqld_path_len,
|
||||
help_option, sizeof(help_option)))
|
||||
if (create_mysqld_command(&cmd, &mysqld_path, &help_option))
|
||||
goto err;
|
||||
|
||||
bzero(result, FN_REFLEN);
|
||||
@@ -198,7 +229,8 @@ int Instance_options::fill_mysqld_real_path()
|
||||
/* chop the path of at [OPTIONS] */
|
||||
if ((options_str= strstr(result, "[OPTIONS]")))
|
||||
*options_str= '\0';
|
||||
mysqld_real_path= strdup_root(&alloc, result);
|
||||
mysqld_real_path.str= strdup_root(&alloc, result);
|
||||
mysqld_real_path.length= strlen(mysqld_real_path.str);
|
||||
}
|
||||
err:
|
||||
if (rc)
|
||||
@@ -255,8 +287,7 @@ int Instance_options::fill_log_options()
|
||||
else
|
||||
{
|
||||
/* below is safe, as --datadir always has a value */
|
||||
strmake(datadir,
|
||||
strchr(mysqld_datadir, '=') + 1, MAX_LOG_OPTION_LENGTH - 1);
|
||||
strmake(datadir, mysqld_datadir, MAX_LOG_OPTION_LENGTH - 1);
|
||||
}
|
||||
|
||||
if (gethostname(hostname,sizeof(hostname)-1) < 0)
|
||||
@@ -342,7 +373,6 @@ err:
|
||||
|
||||
int Instance_options::get_pid_filename(char *result)
|
||||
{
|
||||
const char *pid_file= mysqld_pid_file;
|
||||
char datadir[MAX_PATH_LEN];
|
||||
|
||||
if (mysqld_datadir == NULL)
|
||||
@@ -352,14 +382,10 @@ int Instance_options::get_pid_filename(char *result)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
strxnmov(datadir, MAX_PATH_LEN - 1, strchr(mysqld_datadir, '=') + 1,
|
||||
"/", NullS);
|
||||
|
||||
DBUG_ASSERT(mysqld_pid_file);
|
||||
pid_file= strchr(pid_file, '=') + 1;
|
||||
strxnmov(datadir, MAX_PATH_LEN - 1, mysqld_datadir, "/", NullS);
|
||||
|
||||
/* get the full path to the pidfile */
|
||||
my_load_path(result, pid_file, datadir);
|
||||
my_load_path(result, mysqld_pid_file, datadir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -388,23 +414,23 @@ pid_t Instance_options::get_pid()
|
||||
}
|
||||
|
||||
|
||||
int Instance_options::complete_initialization(const char *default_path,
|
||||
uint instance_type)
|
||||
int Instance_options::complete_initialization(const char *default_path)
|
||||
{
|
||||
int arg_idx;
|
||||
const char *tmp;
|
||||
char *end;
|
||||
|
||||
if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path)))
|
||||
if (!mysqld_path.str && !(mysqld_path.str= strdup_root(&alloc, default_path)))
|
||||
goto err;
|
||||
|
||||
// it's safe to cast this to char* since this is a buffer we are allocating
|
||||
end= convert_dirname((char*)mysqld_path, mysqld_path, NullS);
|
||||
end= convert_dirname((char*)mysqld_path.str, mysqld_path.str, NullS);
|
||||
end[-1]= 0;
|
||||
|
||||
mysqld_path_len= strlen(mysqld_path);
|
||||
mysqld_path.length= strlen(mysqld_path.str);
|
||||
|
||||
if (mysqld_port)
|
||||
mysqld_port_val= atoi(strchr(mysqld_port, '=') + 1);
|
||||
mysqld_port_val= atoi(mysqld_port);
|
||||
|
||||
if (shutdown_delay)
|
||||
shutdown_delay_val= atoi(shutdown_delay);
|
||||
@@ -412,7 +438,7 @@ int Instance_options::complete_initialization(const char *default_path,
|
||||
if (!(tmp= strdup_root(&alloc, "--no-defaults")))
|
||||
goto err;
|
||||
|
||||
if (!(mysqld_pid_file))
|
||||
if (!mysqld_pid_file)
|
||||
{
|
||||
char pidfilename[MAX_PATH_LEN];
|
||||
char hostname[MAX_PATH_LEN];
|
||||
@@ -421,26 +447,27 @@ int Instance_options::complete_initialization(const char *default_path,
|
||||
If we created only one istance [mysqld], because no config. files were
|
||||
found, we would like to model mysqld pid file values.
|
||||
*/
|
||||
|
||||
if (!gethostname(hostname, sizeof(hostname) - 1))
|
||||
{
|
||||
if (instance_type & DEFAULT_SINGLE_INSTANCE)
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", hostname,
|
||||
".pid", NullS);
|
||||
if (Instance::is_mysqld_compatible_name(&instance_name))
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, hostname, ".pid", NullS);
|
||||
else
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name,
|
||||
"-", hostname, ".pid", NullS);
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, instance_name.str, "-",
|
||||
hostname, ".pid", NullS);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (instance_type & DEFAULT_SINGLE_INSTANCE)
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", "mysql",
|
||||
".pid", NullS);
|
||||
if (Instance::is_mysqld_compatible_name(&instance_name))
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, "mysql", ".pid", NullS);
|
||||
else
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, "--pid-file=", instance_name,
|
||||
".pid", NullS);
|
||||
strxnmov(pidfilename, MAX_PATH_LEN - 1, instance_name.str, ".pid",
|
||||
NullS);
|
||||
}
|
||||
|
||||
add_option(pidfilename);
|
||||
Named_value option((char *) "pid-file", pidfilename);
|
||||
|
||||
set_option(&option);
|
||||
}
|
||||
|
||||
if (get_pid_filename(pid_file_with_path))
|
||||
@@ -448,20 +475,37 @@ int Instance_options::complete_initialization(const char *default_path,
|
||||
|
||||
/* we need to reserve space for the final zero + possible default options */
|
||||
if (!(argv= (char**)
|
||||
alloc_root(&alloc, (options_array.elements + 1
|
||||
alloc_root(&alloc, (get_num_options() + 1
|
||||
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
|
||||
goto err;
|
||||
filled_default_options= 0;
|
||||
|
||||
/* the path must be first in the argv */
|
||||
if (add_to_argv(mysqld_path))
|
||||
if (add_to_argv(mysqld_path.str))
|
||||
goto err;
|
||||
|
||||
if (add_to_argv(tmp))
|
||||
goto err;
|
||||
|
||||
memcpy((gptr) (argv + filled_default_options), options_array.buffer,
|
||||
options_array.elements*sizeof(char*));
|
||||
argv[filled_default_options + options_array.elements]= 0;
|
||||
arg_idx= filled_default_options;
|
||||
for (int opt_idx= 0; opt_idx < get_num_options(); ++opt_idx)
|
||||
{
|
||||
char option_str[MAX_OPTION_STR_LEN];
|
||||
Named_value option= get_option(opt_idx);
|
||||
|
||||
if (is_option_im_specific(option.get_name()))
|
||||
continue;
|
||||
|
||||
char *ptr= strxnmov(option_str, MAX_OPTION_LEN + 3, "--", option.get_name(),
|
||||
NullS);
|
||||
|
||||
if (option.get_value()[0])
|
||||
strxnmov(ptr, MAX_OPTION_LEN + 2, "=", option.get_value(), NullS);
|
||||
|
||||
argv[arg_idx++]= strdup_root(&alloc, option_str);
|
||||
}
|
||||
|
||||
argv[arg_idx]= 0;
|
||||
|
||||
if (fill_log_options() || fill_mysqld_real_path() || fill_instance_version())
|
||||
goto err;
|
||||
@@ -473,75 +517,91 @@ err:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Assigns given value to the appropriate option from the class.
|
||||
|
||||
SYNOPSYS
|
||||
add_option()
|
||||
option string with the option prefixed by --
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
The method is called from the option handling routine.
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - error occured
|
||||
*/
|
||||
|
||||
int Instance_options::add_option(const char* option)
|
||||
bool Instance_options::set_option(Named_value *option)
|
||||
{
|
||||
char *tmp;
|
||||
enum { SAVE_VALUE= 1, SAVE_WHOLE, SAVE_WHOLE_AND_ADD };
|
||||
struct selected_options_st
|
||||
bool err_status;
|
||||
int idx= find_option(option->get_name());
|
||||
char *option_name_str;
|
||||
char *option_value_str;
|
||||
|
||||
if (!(option_name_str= Named_value::alloc_str(option->get_name())))
|
||||
return TRUE;
|
||||
|
||||
if (!(option_value_str= Named_value::alloc_str(option->get_value())))
|
||||
{
|
||||
Named_value::free_str(&option_name_str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Named_value option_copy(option_name_str, option_value_str);
|
||||
|
||||
if (idx < 0)
|
||||
err_status= options.add_element(&option_copy);
|
||||
else
|
||||
err_status= options.replace_element(idx, &option_copy);
|
||||
|
||||
if (!err_status)
|
||||
update_var(option_copy.get_name(), option_copy.get_value());
|
||||
else
|
||||
option_copy.free();
|
||||
|
||||
return err_status;
|
||||
}
|
||||
|
||||
|
||||
void Instance_options::unset_option(const char *option_name)
|
||||
{
|
||||
int idx= find_option(option_name);
|
||||
|
||||
if (idx < 0)
|
||||
return; /* the option has not been set. */
|
||||
|
||||
options.remove_element(idx);
|
||||
|
||||
update_var(option_name, NULL);
|
||||
}
|
||||
|
||||
|
||||
void Instance_options::update_var(const char *option_name,
|
||||
const char *option_value)
|
||||
{
|
||||
struct options_st
|
||||
{
|
||||
const char *name;
|
||||
uint length;
|
||||
const char **value;
|
||||
uint type;
|
||||
} options[]=
|
||||
uint name_len;
|
||||
const char **var;
|
||||
} options_def[]=
|
||||
{
|
||||
{"--socket=", 9, &mysqld_socket, SAVE_WHOLE_AND_ADD},
|
||||
{"--port=", 7, &mysqld_port, SAVE_WHOLE_AND_ADD},
|
||||
{"--datadir=", 10, &mysqld_datadir, SAVE_WHOLE_AND_ADD},
|
||||
{"--bind-address=", 15, &mysqld_bind_address, SAVE_WHOLE_AND_ADD},
|
||||
{"--pid-file=", 11, &mysqld_pid_file, SAVE_WHOLE_AND_ADD},
|
||||
{"--mysqld-path=", 14, &mysqld_path, SAVE_VALUE},
|
||||
{"--nonguarded", 9, &nonguarded, SAVE_WHOLE},
|
||||
{"--shutdown_delay", 9, &shutdown_delay, SAVE_VALUE},
|
||||
{NULL, 0, NULL, 0}
|
||||
{"socket", 6, &mysqld_socket},
|
||||
{"port", 4, &mysqld_port},
|
||||
{"datadir", 7, &mysqld_datadir},
|
||||
{"pid-file", 8, &mysqld_pid_file},
|
||||
{"nonguarded", 10, &nonguarded},
|
||||
{"mysqld-path", 11, (const char **) &mysqld_path.str},
|
||||
{"shutdown-delay", 14, &shutdown_delay},
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
struct selected_options_st *selected_options;
|
||||
|
||||
if (!(tmp= strdup_root(&alloc, option)))
|
||||
goto err;
|
||||
|
||||
for (selected_options= options; selected_options->name; selected_options++)
|
||||
for (options_st *opt= options_def; opt->name; ++opt)
|
||||
{
|
||||
if (strncmp(tmp, selected_options->name, selected_options->length) == 0)
|
||||
switch (selected_options->type) {
|
||||
case SAVE_WHOLE_AND_ADD:
|
||||
*(selected_options->value)= tmp;
|
||||
insert_dynamic(&options_array,(gptr) &tmp);
|
||||
return 0;
|
||||
case SAVE_VALUE:
|
||||
*(selected_options->value)= strchr(tmp, '=') + 1;
|
||||
return 0;
|
||||
case SAVE_WHOLE:
|
||||
*(selected_options->value)= tmp;
|
||||
return 0;
|
||||
default:
|
||||
if (!strncmp(opt->name, option_name, opt->name_len))
|
||||
{
|
||||
*(opt->var)= option_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we haven't returned earlier we should just save the option */
|
||||
insert_dynamic(&options_array,(gptr) &tmp);
|
||||
|
||||
return 0;
|
||||
int Instance_options::find_option(const char *option_name)
|
||||
{
|
||||
for (int i= 0; i < get_num_options(); i++)
|
||||
{
|
||||
if (!strcmp(get_option(i).get_name(), option_name))
|
||||
return i;
|
||||
}
|
||||
|
||||
err:
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -559,7 +619,10 @@ int Instance_options::add_to_argv(const char* option)
|
||||
void Instance_options::print_argv()
|
||||
{
|
||||
int i;
|
||||
printf("printing out an instance %s argv:\n", instance_name);
|
||||
|
||||
printf("printing out an instance %s argv:\n",
|
||||
(const char *) instance_name.str);
|
||||
|
||||
for (i=0; argv[i] != NULL; i++)
|
||||
printf("argv: %s\n", argv[i]);
|
||||
}
|
||||
@@ -570,17 +633,17 @@ void Instance_options::print_argv()
|
||||
Return value: 0 - ok. 1 - unable to allocate memory.
|
||||
*/
|
||||
|
||||
int Instance_options::init(const char *instance_name_arg)
|
||||
int Instance_options::init(const LEX_STRING *instance_name_arg)
|
||||
{
|
||||
instance_name_len= strlen(instance_name_arg);
|
||||
instance_name.length= instance_name_arg->length;
|
||||
|
||||
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
|
||||
|
||||
if (my_init_dynamic_array(&options_array, sizeof(char*), 0, 32))
|
||||
if (options.init())
|
||||
goto err;
|
||||
|
||||
if (!(instance_name= strmake_root(&alloc, (char*) instance_name_arg,
|
||||
instance_name_len)))
|
||||
if (!(instance_name.str= strmake_root(&alloc, instance_name_arg->str,
|
||||
instance_name_arg->length)))
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
@@ -593,6 +656,4 @@ err:
|
||||
Instance_options::~Instance_options()
|
||||
{
|
||||
free_root(&alloc, MYF(0));
|
||||
delete_dynamic(&options_array);
|
||||
}
|
||||
|
||||
|
@@ -18,8 +18,9 @@
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
#include "parse.h"
|
||||
#include "portability.h"
|
||||
#include "portability.h" /* for pid_t on Win32 */
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
@@ -35,25 +36,26 @@
|
||||
don't have to synchronize between threads.
|
||||
*/
|
||||
|
||||
#define USUAL_INSTANCE 0
|
||||
#define DEFAULT_SINGLE_INSTANCE 1
|
||||
|
||||
class Instance_options
|
||||
{
|
||||
public:
|
||||
Instance_options() :
|
||||
mysqld_version(0), mysqld_socket(0), mysqld_datadir(0),
|
||||
mysqld_bind_address(0), mysqld_pid_file(0), mysqld_port(0),
|
||||
mysqld_port_val(0), mysqld_path(0), mysqld_real_path(0),
|
||||
nonguarded(0), shutdown_delay(0),
|
||||
shutdown_delay_val(0), filled_default_options(0)
|
||||
{}
|
||||
/* The operation is used to check if the option is IM-specific or not. */
|
||||
static bool is_option_im_specific(const char *option_name);
|
||||
|
||||
public:
|
||||
Instance_options();
|
||||
~Instance_options();
|
||||
/* fills in argv */
|
||||
int complete_initialization(const char *default_path, uint instance_type);
|
||||
int complete_initialization(const char *default_path);
|
||||
|
||||
int add_option(const char* option);
|
||||
int init(const char *instance_name_arg);
|
||||
bool set_option(Named_value *option);
|
||||
void unset_option(const char *option_name);
|
||||
|
||||
inline int get_num_options() const;
|
||||
inline Named_value get_option(int idx) const;
|
||||
|
||||
public:
|
||||
int init(const LEX_STRING *instance_name_arg);
|
||||
pid_t get_pid();
|
||||
int get_pid_filename(char *result);
|
||||
int unlink_pidfile();
|
||||
@@ -66,7 +68,6 @@ public:
|
||||
*/
|
||||
enum { MAX_PATH_LEN= 512 };
|
||||
enum { MAX_NUMBER_OF_DEFAULT_OPTIONS= 2 };
|
||||
enum { MEM_ROOT_BLOCK_SIZE= 512 };
|
||||
char pid_file_with_path[MAX_PATH_LEN];
|
||||
char **argv;
|
||||
/*
|
||||
@@ -77,23 +78,18 @@ public:
|
||||
/* We need the some options, so we store them as a separate pointers */
|
||||
const char *mysqld_socket;
|
||||
const char *mysqld_datadir;
|
||||
const char *mysqld_bind_address;
|
||||
const char *mysqld_pid_file;
|
||||
const char *mysqld_port;
|
||||
uint mysqld_port_val;
|
||||
const char *instance_name;
|
||||
uint instance_name_len;
|
||||
const char *mysqld_path;
|
||||
uint mysqld_path_len;
|
||||
const char *mysqld_real_path;
|
||||
LEX_STRING instance_name;
|
||||
LEX_STRING mysqld_path;
|
||||
LEX_STRING mysqld_real_path;
|
||||
const char *nonguarded;
|
||||
const char *shutdown_delay;
|
||||
uint shutdown_delay_val;
|
||||
/* log enums are defined in parse.h */
|
||||
char *logs[3];
|
||||
|
||||
/* this value is computed and cashed here */
|
||||
DYNAMIC_ARRAY options_array;
|
||||
private:
|
||||
int fill_log_options();
|
||||
int fill_instance_version();
|
||||
@@ -101,9 +97,27 @@ private:
|
||||
int add_to_argv(const char *option);
|
||||
int get_default_option(char *result, size_t result_len,
|
||||
const char *option_name);
|
||||
|
||||
void update_var(const char *option_name, const char *option_value);
|
||||
int find_option(const char *option_name);
|
||||
|
||||
private:
|
||||
uint filled_default_options;
|
||||
MEM_ROOT alloc;
|
||||
|
||||
Named_value_arr options;
|
||||
};
|
||||
|
||||
|
||||
inline int Instance_options::get_num_options() const
|
||||
{
|
||||
return options.get_size();
|
||||
}
|
||||
|
||||
|
||||
inline Named_value Instance_options::get_option(int idx) const
|
||||
{
|
||||
return options.get_element(idx);
|
||||
}
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_OPTIONS_H */
|
||||
|
@@ -19,21 +19,23 @@
|
||||
#endif
|
||||
|
||||
#include "listener.h"
|
||||
#include "priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
#include <violite.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifndef __WIN__
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "thread_registry.h"
|
||||
#include "options.h"
|
||||
#include "instance_map.h"
|
||||
#include "log.h"
|
||||
#include "mysql_connection.h"
|
||||
#include "options.h"
|
||||
#include "portability.h"
|
||||
#include "priv.h"
|
||||
#include "thread_registry.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -62,8 +64,7 @@ private:
|
||||
|
||||
|
||||
Listener_thread::Listener_thread(const Listener_thread_args &args) :
|
||||
Listener_thread_args(args.thread_registry, args.options, args.user_map,
|
||||
args.instance_map)
|
||||
Listener_thread_args(args.thread_registry, args.user_map, args.instance_map)
|
||||
,total_connection_count(0)
|
||||
,thread_info(pthread_self())
|
||||
,num_sockets(0)
|
||||
@@ -234,14 +235,16 @@ int Listener_thread::create_tcp_socket()
|
||||
bzero(&ip_socket_address, sizeof(ip_socket_address));
|
||||
|
||||
ulong im_bind_addr;
|
||||
if (options.bind_address != 0)
|
||||
if (Options::Main::bind_address != 0)
|
||||
{
|
||||
if ((im_bind_addr= (ulong) inet_addr(options.bind_address)) == INADDR_NONE)
|
||||
im_bind_addr= (ulong) inet_addr(Options::Main::bind_address);
|
||||
|
||||
if (im_bind_addr == INADDR_NONE)
|
||||
im_bind_addr= htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
im_bind_addr= htonl(INADDR_ANY);
|
||||
uint im_port= options.port_number;
|
||||
uint im_port= Options::Main::port_number;
|
||||
|
||||
ip_socket_address.sin_family= AF_INET;
|
||||
ip_socket_address.sin_addr.s_addr= im_bind_addr;
|
||||
@@ -295,7 +298,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
|
||||
bzero(&unix_socket_address, sizeof(unix_socket_address));
|
||||
|
||||
unix_socket_address.sun_family= AF_UNIX;
|
||||
strmake(unix_socket_address.sun_path, options.socket_file_name,
|
||||
strmake(unix_socket_address.sun_path, Options::Main::socket_file_name,
|
||||
sizeof(unix_socket_address.sun_path));
|
||||
unlink(unix_socket_address.sun_path); // in case we have stale socket file
|
||||
|
||||
|
@@ -27,23 +27,19 @@
|
||||
pthread_handler_t listener(void *arg);
|
||||
|
||||
class Thread_registry;
|
||||
struct Options;
|
||||
class User_map;
|
||||
class Instance_map;
|
||||
|
||||
struct Listener_thread_args
|
||||
{
|
||||
Thread_registry &thread_registry;
|
||||
const Options &options;
|
||||
const User_map &user_map;
|
||||
Instance_map &instance_map;
|
||||
|
||||
Listener_thread_args(Thread_registry &thread_registry_arg,
|
||||
const Options &options_arg,
|
||||
const User_map &user_map_arg,
|
||||
Instance_map &instance_map_arg) :
|
||||
thread_registry(thread_registry_arg)
|
||||
,options(options_arg)
|
||||
,user_map(user_map_arg)
|
||||
,instance_map(instance_map_arg)
|
||||
{}
|
||||
|
@@ -14,14 +14,16 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "portability.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h" /* for vsnprintf() on Windows. */
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- add flexible header support
|
||||
@@ -71,7 +73,7 @@ static inline void log(FILE *file, const char *format, va_list args)
|
||||
{
|
||||
int size= sizeof(buff_stack) * 2;
|
||||
buff_msg= (char*) my_malloc(size, MYF(0));
|
||||
while (true)
|
||||
while (TRUE)
|
||||
{
|
||||
if (buff_msg == 0)
|
||||
{
|
||||
|
@@ -14,39 +14,55 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "manager.h"
|
||||
|
||||
#include "priv.h"
|
||||
#include "thread_registry.h"
|
||||
#include "listener.h"
|
||||
#include "instance_map.h"
|
||||
#include "options.h"
|
||||
#include "user_map.h"
|
||||
#include "log.h"
|
||||
#include "guardian.h"
|
||||
|
||||
#include <my_sys.h>
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <signal.h>
|
||||
#include <my_sys.h>
|
||||
#include <thr_alarm.h>
|
||||
|
||||
#include <signal.h>
|
||||
#ifndef __WIN__
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include "exit_codes.h"
|
||||
#include "guardian.h"
|
||||
#include "instance_map.h"
|
||||
#include "listener.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "priv.h"
|
||||
#include "thread_registry.h"
|
||||
#include "user_map.h"
|
||||
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid)
|
||||
{
|
||||
if (FILE *pid_file= my_fopen(pid_file_name,
|
||||
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
|
||||
FILE *pid_file;
|
||||
|
||||
if (!(pid_file= my_fopen(pid_file_name, O_WRONLY | O_CREAT | O_BINARY,
|
||||
MYF(0))))
|
||||
{
|
||||
fprintf(pid_file, "%d\n", (int) pid);
|
||||
my_fclose(pid_file, MYF(0));
|
||||
return 0;
|
||||
}
|
||||
log_error("can't create pid file %s: errno=%d, %s",
|
||||
pid_file_name, errno, strerror(errno));
|
||||
log_error("Error: can not create pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fprintf(pid_file, "%d\n", (int) pid) <= 0)
|
||||
{
|
||||
log_error("Error: can not write to pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
my_fclose(pid_file, MYF(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef __WIN__
|
||||
@@ -82,14 +98,14 @@ bool have_signal;
|
||||
|
||||
void onsignal(int signo)
|
||||
{
|
||||
have_signal= true;
|
||||
have_signal= TRUE;
|
||||
}
|
||||
|
||||
void set_signals(sigset_t *set)
|
||||
{
|
||||
signal(SIGINT, onsignal);
|
||||
signal(SIGTERM, onsignal);
|
||||
have_signal= false;
|
||||
have_signal= FALSE;
|
||||
}
|
||||
|
||||
int my_sigwait(const sigset_t *set, int *sig)
|
||||
@@ -109,10 +125,16 @@ int my_sigwait(const sigset_t *set, int *sig)
|
||||
listener thread, write pid file and enter into signal handling.
|
||||
See also comments in mysqlmanager.cc to picture general Instance Manager
|
||||
architecture.
|
||||
|
||||
TODO: how about returning error status.
|
||||
*/
|
||||
|
||||
void manager(const Options &options)
|
||||
void manager()
|
||||
{
|
||||
int err_code;
|
||||
const char *err_msg;
|
||||
bool shutdown_complete= FALSE;
|
||||
|
||||
Thread_registry thread_registry;
|
||||
/*
|
||||
All objects created in the manager() function live as long as
|
||||
@@ -121,31 +143,60 @@ void manager(const Options &options)
|
||||
*/
|
||||
|
||||
User_map user_map;
|
||||
Instance_map instance_map(options.default_mysqld_path);
|
||||
Instance_map instance_map(Options::Main::default_mysqld_path);
|
||||
Guardian_thread guardian_thread(thread_registry,
|
||||
&instance_map,
|
||||
options.monitoring_interval);
|
||||
Options::Main::monitoring_interval);
|
||||
|
||||
Listener_thread_args listener_args(thread_registry, options, user_map,
|
||||
instance_map);
|
||||
Listener_thread_args listener_args(thread_registry, user_map, instance_map);
|
||||
|
||||
manager_pid= getpid();
|
||||
instance_map.guardian= &guardian_thread;
|
||||
|
||||
if (instance_map.init() || user_map.init())
|
||||
return;
|
||||
/* Initialize instance map. */
|
||||
|
||||
if (user_map.load(options.password_file_name))
|
||||
if (instance_map.init())
|
||||
{
|
||||
log_error("Error: can not initialize instance list: out of memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize user map and load password file. */
|
||||
|
||||
if (user_map.init())
|
||||
{
|
||||
log_error("Error: can not initialize user list: out of memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((err_code= user_map.load(Options::Main::password_file_name, &err_msg)))
|
||||
{
|
||||
if (err_code == ERR_PASSWORD_FILE_DOES_NOT_EXIST &&
|
||||
Options::Main::mysqld_safe_compatible)
|
||||
{
|
||||
/*
|
||||
The password file does not exist, but we are running in
|
||||
mysqld_safe-compatible mode. Continue, but complain in log.
|
||||
*/
|
||||
|
||||
log_error("Warning: password file does not exist, "
|
||||
"nobody will be able to connect to Instance Manager.");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Error: %s.", (const char *) err_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* write Instance Manager pid file */
|
||||
|
||||
log_info("IM pid file: '%s'; PID: %d.",
|
||||
(const char *) options.pid_file_name,
|
||||
(const char *) Options::Main::pid_file_name,
|
||||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(options.pid_file_name, manager_pid))
|
||||
return;
|
||||
if (create_pid_file(Options::Main::pid_file_name, manager_pid))
|
||||
return; /* necessary logging has been already done. */
|
||||
|
||||
sigset_t mask;
|
||||
set_signals(&mask);
|
||||
@@ -198,18 +249,24 @@ void manager(const Options &options)
|
||||
To work nicely with LinuxThreads, the signal thread is the first thread
|
||||
in the process.
|
||||
*/
|
||||
int signo;
|
||||
bool shutdown_complete;
|
||||
|
||||
shutdown_complete= FALSE;
|
||||
{
|
||||
instance_map.guardian->lock();
|
||||
instance_map.lock();
|
||||
|
||||
if (instance_map.flush_instances())
|
||||
int flush_instances_status= instance_map.flush_instances();
|
||||
|
||||
instance_map.unlock();
|
||||
instance_map.guardian->unlock();
|
||||
|
||||
if (flush_instances_status)
|
||||
{
|
||||
log_error("Cannot init instances repository. This might be caused by "
|
||||
"the wrong config file options. For instance, missing mysqld "
|
||||
"binary. Aborting.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
After the list of guarded instances have been initialized,
|
||||
@@ -219,6 +276,7 @@ void manager(const Options &options)
|
||||
|
||||
while (!shutdown_complete)
|
||||
{
|
||||
int signo;
|
||||
int status= 0;
|
||||
|
||||
if ((status= my_sigwait(&mask, &signo)) != 0)
|
||||
@@ -245,7 +303,7 @@ void manager(const Options &options)
|
||||
{
|
||||
if (!guardian_thread.is_stopped())
|
||||
{
|
||||
bool stop_instances= true;
|
||||
bool stop_instances= TRUE;
|
||||
guardian_thread.request_shutdown(stop_instances);
|
||||
pthread_cond_signal(&guardian_thread.COND_guardian);
|
||||
}
|
||||
@@ -259,7 +317,7 @@ void manager(const Options &options)
|
||||
|
||||
err:
|
||||
/* delete the pid file */
|
||||
my_delete(options.pid_file_name, MYF(0));
|
||||
my_delete(Options::Main::pid_file_name, MYF(0));
|
||||
|
||||
#ifndef __WIN__
|
||||
/* free alarm structures */
|
||||
@@ -267,4 +325,3 @@ err:
|
||||
/* don't pthread_exit to kill all threads who did not shut down in time */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -16,9 +16,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
struct Options;
|
||||
|
||||
void manager(const Options &options);
|
||||
void manager();
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
|
@@ -14,15 +14,14 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "messages.h"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_com.h>
|
||||
|
||||
#include "mysqld_error.h"
|
||||
#include "mysql_manager_error.h"
|
||||
|
||||
#include <mysql_com.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
static const char *mysqld_error_message(unsigned sql_errno)
|
||||
{
|
||||
@@ -70,6 +69,23 @@ static const char *mysqld_error_message(unsigned sql_errno)
|
||||
"in the instance options";
|
||||
case ER_ACCESS_OPTION_FILE:
|
||||
return "Cannot open the option file to edit. Check permissions";
|
||||
case ER_DROP_ACTIVE_INSTANCE:
|
||||
return "Cannot drop an active instance. You should stop it first";
|
||||
case ER_CREATE_EXISTING_INSTANCE:
|
||||
return "Instance already exists";
|
||||
case ER_INSTANCE_MISCONFIGURED:
|
||||
return "Instance is misconfigured. Cannot start it";
|
||||
case ER_MALFORMED_INSTANCE_NAME:
|
||||
return "Malformed instance name.";
|
||||
case ER_INSTANCE_IS_ACTIVE:
|
||||
return "The instance is active. Stop the instance first";
|
||||
case ER_THERE_IS_ACTIVE_INSTACE:
|
||||
return "At least one instance is active. Stop all instances first";
|
||||
case ER_INCOMPATIBLE_OPTION:
|
||||
return "Instance Manager-specific options are prohibited from being used "
|
||||
"in the configuration of mysqld-compatible instances";
|
||||
case ER_CONF_FILE_DOES_NOT_EXIST:
|
||||
return "Configuration file does not exist";
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
return 0;
|
||||
|
@@ -20,22 +20,24 @@
|
||||
|
||||
#include "mysql_connection.h"
|
||||
|
||||
#include "priv.h"
|
||||
#include "mysql_manager_error.h"
|
||||
#include "mysqld_error.h"
|
||||
#include "thread_registry.h"
|
||||
#include "log.h"
|
||||
#include "user_map.h"
|
||||
#include "protocol.h"
|
||||
#include "messages.h"
|
||||
#include "command.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include <mysql.h>
|
||||
#include <violite.h>
|
||||
#include <mysql_com.h>
|
||||
#include <m_string.h>
|
||||
#include <m_string.h>
|
||||
#include <my_global.h>
|
||||
#include <mysql_com.h>
|
||||
#include <mysql.h>
|
||||
#include <my_sys.h>
|
||||
#include <violite.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "mysqld_error.h"
|
||||
#include "mysql_manager_error.h"
|
||||
#include "parse.h"
|
||||
#include "priv.h"
|
||||
#include "protocol.h"
|
||||
#include "thread_registry.h"
|
||||
#include "user_map.h"
|
||||
|
||||
|
||||
Mysql_connection_thread_args::Mysql_connection_thread_args(
|
||||
@@ -190,8 +192,6 @@ void Mysql_connection_thread::run()
|
||||
int Mysql_connection_thread::check_connection()
|
||||
{
|
||||
ulong pkt_len=0; // to hold client reply length
|
||||
/* maximum size of the version string */
|
||||
enum { MAX_VERSION_LENGTH= 80 };
|
||||
|
||||
/* buffer for the first packet */ /* packet contains: */
|
||||
char buff[MAX_VERSION_LENGTH + 1 + // server version, 0-ended
|
||||
@@ -202,8 +202,8 @@ int Mysql_connection_thread::check_connection()
|
||||
char *pos= buff;
|
||||
ulong server_flags;
|
||||
|
||||
memcpy(pos, mysqlmanager_version, mysqlmanager_version_length + 1);
|
||||
pos+= mysqlmanager_version_length + 1;
|
||||
memcpy(pos, mysqlmanager_version.str, mysqlmanager_version.length + 1);
|
||||
pos+= mysqlmanager_version.length + 1;
|
||||
|
||||
int4store((uchar*) pos, connection_id);
|
||||
pos+= 4;
|
||||
@@ -271,12 +271,14 @@ int Mysql_connection_thread::check_connection()
|
||||
const char *user= pos;
|
||||
const char *password= strend(user)+1;
|
||||
ulong password_len= *password++;
|
||||
LEX_STRING user_name= { (char *) user, password - user - 2 };
|
||||
|
||||
if (password_len != SCRAMBLE_LENGTH)
|
||||
{
|
||||
net_send_error(&net, ER_ACCESS_DENIED_ERROR);
|
||||
return 1;
|
||||
}
|
||||
if (user_map.authenticate(user, password-user-2, password, scramble))
|
||||
if (user_map.authenticate(&user_name, password, scramble))
|
||||
{
|
||||
net_send_error(&net, ER_ACCESS_DENIED_ERROR);
|
||||
return 1;
|
||||
@@ -336,7 +338,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
|
||||
if (Command *command= parse_command(&instance_map, packet))
|
||||
{
|
||||
int res= 0;
|
||||
log_info("query for connection %d successefully parsed",connection_id);
|
||||
log_info("query for connection %d successfully parsed",connection_id);
|
||||
res= command->execute(&net, connection_id);
|
||||
delete command;
|
||||
if (!res)
|
||||
|
@@ -29,5 +29,13 @@
|
||||
#define ER_ACCESS_OPTION_FILE 3008
|
||||
#define ER_OFFSET_ERROR 3009
|
||||
#define ER_READ_FILE 3010
|
||||
#define ER_DROP_ACTIVE_INSTANCE 3011
|
||||
#define ER_CREATE_EXISTING_INSTANCE 3012
|
||||
#define ER_INSTANCE_MISCONFIGURED 3013
|
||||
#define ER_MALFORMED_INSTANCE_NAME 3014
|
||||
#define ER_INSTANCE_IS_ACTIVE 3015
|
||||
#define ER_THERE_IS_ACTIVE_INSTACE 3016
|
||||
#define ER_INCOMPATIBLE_OPTION 3017
|
||||
#define ER_CONF_FILE_DOES_NOT_EXIST 3018
|
||||
|
||||
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H */
|
||||
|
@@ -15,25 +15,30 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "manager.h"
|
||||
|
||||
#include "options.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <my_sys.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef __WIN__
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "manager.h"
|
||||
#include "options.h"
|
||||
#include "user_management_commands.h"
|
||||
|
||||
#ifdef __WIN__
|
||||
#include "windowsservice.h"
|
||||
#include "IMService.h"
|
||||
#include "WindowsService.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Few notes about Instance Manager architecture:
|
||||
Instance Manager consisits of two processes: the angel process, and the
|
||||
@@ -59,13 +64,12 @@
|
||||
*/
|
||||
|
||||
static void init_environment(char *progname);
|
||||
|
||||
#ifndef __WIN__
|
||||
static void daemonize(const char *log_file_name);
|
||||
static void angel(const Options &options);
|
||||
static void angel();
|
||||
static struct passwd *check_user(const char *user);
|
||||
static int set_user(const char *user, struct passwd *user_info);
|
||||
#else
|
||||
int HandleServiceOptions(Options options);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -81,41 +85,61 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int return_value= 1;
|
||||
init_environment(argv[0]);
|
||||
Options options;
|
||||
|
||||
if (options.load(argc, argv))
|
||||
goto err;
|
||||
if ((return_value= Options::load(argc, argv)))
|
||||
goto main_end;
|
||||
|
||||
if (Options::User_management::cmd)
|
||||
{
|
||||
return_value= Options::User_management::cmd->execute();
|
||||
|
||||
goto main_end;
|
||||
}
|
||||
|
||||
#ifndef __WIN__
|
||||
|
||||
struct passwd *user_info;
|
||||
|
||||
if ((user_info= check_user(options.user)))
|
||||
if ((user_info= check_user(Options::Daemon::user)))
|
||||
{
|
||||
if (set_user(options.user, user_info))
|
||||
goto err;
|
||||
if (set_user(Options::Daemon::user, user_info))
|
||||
{
|
||||
return_value= 1;
|
||||
goto main_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.run_as_service)
|
||||
if (Options::Daemon::run_as_service)
|
||||
{
|
||||
/* forks, and returns only in child */
|
||||
daemonize(options.log_file_name);
|
||||
daemonize(Options::Daemon::log_file_name);
|
||||
/* forks again, and returns only in child: parent becomes angel */
|
||||
angel(options);
|
||||
angel();
|
||||
}
|
||||
|
||||
manager();
|
||||
|
||||
#else
|
||||
if (!options.stand_alone)
|
||||
|
||||
if (!Options::Service::stand_alone)
|
||||
{
|
||||
if (HandleServiceOptions(options))
|
||||
goto err;
|
||||
if (HandleServiceOptions())
|
||||
{
|
||||
return_value= 1;
|
||||
goto main_end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
manager();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
manager(options);
|
||||
return_value= 0;
|
||||
|
||||
err:
|
||||
options.cleanup();
|
||||
main_end:
|
||||
Options::cleanup();
|
||||
my_end(0);
|
||||
return return_value;
|
||||
}
|
||||
@@ -200,7 +224,7 @@ static void init_environment(char *progname)
|
||||
MY_INIT(progname);
|
||||
log_init();
|
||||
umask(0117);
|
||||
srand(time(0));
|
||||
srand((unsigned int) time(0));
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +322,7 @@ void terminate(int signo)
|
||||
Angel process will exit silently if mysqlmanager exits normally.
|
||||
*/
|
||||
|
||||
static void angel(const Options &options)
|
||||
static void angel()
|
||||
{
|
||||
/* install signal handlers */
|
||||
sigset_t zeromask; // to sigsuspend in parent
|
||||
@@ -341,10 +365,10 @@ spawn:
|
||||
pid= getpid(); /* Get our pid. */
|
||||
|
||||
log_info("Angel pid file: '%s'; PID: %d.",
|
||||
(const char *) options.angel_pid_file_name,
|
||||
(const char *) Options::Daemon::angel_pid_file_name,
|
||||
(int) pid);
|
||||
|
||||
create_pid_file(Options::angel_pid_file_name, pid);
|
||||
create_pid_file(Options::Daemon::angel_pid_file_name, pid);
|
||||
|
||||
while (child_status == CHILD_OK && is_terminated == 0)
|
||||
sigsuspend(&zeromask);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user