-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Mysql Protocol #2093
Open
yanglimingcn
wants to merge
1
commit into
apache:master
Choose a base branch
from
yanglimingcn:mysql_proto
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add Mysql Protocol #2093
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
cmake_minimum_required(VERSION 2.8.10) | ||
project(mysql_c++ C CXX) | ||
|
||
# Install dependencies: | ||
# With apt: | ||
# sudo apt-get install libreadline-dev | ||
# sudo apt-get install ncurses-dev | ||
# With yum: | ||
# sudo yum install readline-devel | ||
# sudo yum install ncurses-devel | ||
|
||
option(EXAMPLE_LINK_SO "Whether examples are linked dynamically" OFF) | ||
|
||
execute_process( | ||
COMMAND bash -c "find ${PROJECT_SOURCE_DIR}/../.. -type d -regex \".*output/include$\" | head -n1 | xargs dirname | tr -d '\n'" | ||
OUTPUT_VARIABLE OUTPUT_PATH | ||
) | ||
|
||
set(CMAKE_PREFIX_PATH ${OUTPUT_PATH}) | ||
|
||
include(FindThreads) | ||
include(FindProtobuf) | ||
|
||
# Search for libthrift* by best effort. If it is not found and brpc is | ||
# compiled with thrift protocol enabled, a link error would be reported. | ||
find_library(THRIFT_LIB NAMES thrift) | ||
if (NOT THRIFT_LIB) | ||
set(THRIFT_LIB "") | ||
endif() | ||
find_library(THRIFTNB_LIB NAMES thriftnb) | ||
if (NOT THRIFTNB_LIB) | ||
set(THRIFTNB_LIB "") | ||
endif() | ||
|
||
find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h) | ||
if(EXAMPLE_LINK_SO) | ||
find_library(BRPC_LIB NAMES brpc) | ||
else() | ||
find_library(BRPC_LIB NAMES libbrpc.a brpc) | ||
endif() | ||
if((NOT BRPC_INCLUDE_PATH) OR (NOT BRPC_LIB)) | ||
message(FATAL_ERROR "Fail to find brpc") | ||
endif() | ||
include_directories(${BRPC_INCLUDE_PATH}) | ||
|
||
find_path(GFLAGS_INCLUDE_PATH gflags/gflags.h) | ||
find_library(GFLAGS_LIBRARY NAMES gflags libgflags) | ||
if((NOT GFLAGS_INCLUDE_PATH) OR (NOT GFLAGS_LIBRARY)) | ||
message(FATAL_ERROR "Fail to find gflags") | ||
endif() | ||
include_directories(${GFLAGS_INCLUDE_PATH}) | ||
|
||
execute_process( | ||
COMMAND bash -c "grep \"namespace [_A-Za-z0-9]\\+ {\" ${GFLAGS_INCLUDE_PATH}/gflags/gflags_declare.h | head -1 | awk '{print $2}' | tr -d '\n'" | ||
OUTPUT_VARIABLE GFLAGS_NS | ||
) | ||
if(${GFLAGS_NS} STREQUAL "GFLAGS_NAMESPACE") | ||
execute_process( | ||
COMMAND bash -c "grep \"#define GFLAGS_NAMESPACE [_A-Za-z0-9]\\+\" ${GFLAGS_INCLUDE_PATH}/gflags/gflags_declare.h | head -1 | awk '{print $3}' | tr -d '\n'" | ||
OUTPUT_VARIABLE GFLAGS_NS | ||
) | ||
endif() | ||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
include(CheckFunctionExists) | ||
CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME) | ||
if(NOT HAVE_CLOCK_GETTIME) | ||
set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC") | ||
endif() | ||
endif() | ||
|
||
set(CMAKE_CPP_FLAGS "${DEFINE_CLOCK_GETTIME} -DGFLAGS_NS=${GFLAGS_NS}") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CPP_FLAGS} -DNDEBUG -O2 -D__const__= -pipe -W -Wall -Wno-unused-parameter -fPIC -fno-omit-frame-pointer") | ||
|
||
if(CMAKE_VERSION VERSION_LESS "3.1.3") | ||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||
endif() | ||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||
endif() | ||
else() | ||
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
endif() | ||
|
||
find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h) | ||
find_library(LEVELDB_LIB NAMES leveldb) | ||
if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB)) | ||
message(FATAL_ERROR "Fail to find leveldb") | ||
endif() | ||
include_directories(${LEVELDB_INCLUDE_PATH}) | ||
|
||
find_library(SSL_LIB NAMES ssl) | ||
if (NOT SSL_LIB) | ||
message(FATAL_ERROR "Fail to find ssl") | ||
endif() | ||
|
||
find_library(CRYPTO_LIB NAMES crypto) | ||
if (NOT CRYPTO_LIB) | ||
message(FATAL_ERROR "Fail to find crypto") | ||
endif() | ||
|
||
# find_path(MYSQL_INCLUDE_PATH NAMES mysql/mysql.h) | ||
# find_library(MYSQL_LIB NAMES mysqlclient) | ||
# if (NOT MYSQL_LIB) | ||
# message(FATAL_ERROR "Fail to find mysqlclient") | ||
# endif() | ||
# include_directories(${MYSQL_INCLUDE_PATH}) | ||
|
||
set(DYNAMIC_LIB | ||
${CMAKE_THREAD_LIBS_INIT} | ||
${GFLAGS_LIBRARY} | ||
${PROTOBUF_LIBRARIES} | ||
${LEVELDB_LIB} | ||
${SSL_LIB} | ||
${CRYPTO_LIB} | ||
${THRIFT_LIB} | ||
${THRIFTNB_LIB} | ||
# ${MYSQL_LIB} | ||
dl | ||
) | ||
|
||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
set(DYNAMIC_LIB ${DYNAMIC_LIB} | ||
pthread | ||
"-framework CoreFoundation" | ||
"-framework CoreGraphics" | ||
"-framework CoreData" | ||
"-framework CoreText" | ||
"-framework Security" | ||
"-framework Foundation" | ||
"-Wl,-U,_MallocExtension_ReleaseFreeMemory" | ||
"-Wl,-U,_ProfilerStart" | ||
"-Wl,-U,_ProfilerStop") | ||
endif() | ||
|
||
add_executable(mysql_cli mysql_cli.cpp) | ||
add_executable(mysql_tx mysql_tx.cpp) | ||
add_executable(mysql_stmt mysql_stmt.cpp) | ||
add_executable(mysql_press mysql_press.cpp) | ||
# add_executable(mysqlclient_press mysqlclient_press.cpp) | ||
|
||
set(AUX_LIB readline ncurses) | ||
target_link_libraries(mysql_cli ${BRPC_LIB} ${DYNAMIC_LIB} ${AUX_LIB}) | ||
target_link_libraries(mysql_tx ${BRPC_LIB} ${DYNAMIC_LIB}) | ||
target_link_libraries(mysql_stmt ${BRPC_LIB} ${DYNAMIC_LIB}) | ||
target_link_libraries(mysql_press ${BRPC_LIB} ${DYNAMIC_LIB}) | ||
# target_link_libraries(mysqlclient_press ${BRPC_LIB} ${DYNAMIC_LIB}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// Copyright (c) 2014 Baidu, Inc. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 要改成Apache License header,下同 |
||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// A brpc based command-line interface to talk with mysql-server | ||
|
||
#include <signal.h> | ||
#include <stdio.h> | ||
#include <readline/readline.h> | ||
#include <readline/history.h> | ||
#include <gflags/gflags.h> | ||
#include <butil/logging.h> | ||
#include <brpc/channel.h> | ||
#include <brpc/mysql.h> | ||
#include <brpc/policy/mysql_authenticator.h> | ||
|
||
DEFINE_string(connection_type, "pooled", "Connection type. Available values: pooled, short"); | ||
DEFINE_string(server, "127.0.0.1", "IP Address of server"); | ||
DEFINE_int32(port, 3306, "Port of server"); | ||
DEFINE_string(user, "brpcuser", "user name"); | ||
DEFINE_string(password, "12345678", "password"); | ||
DEFINE_string(schema, "brpc_test", "schema"); | ||
DEFINE_string(params, "", "params"); | ||
DEFINE_string(collation, "utf8mb4_general_ci", "collation"); | ||
DEFINE_int32(timeout_ms, 5000, "RPC timeout in milliseconds"); | ||
DEFINE_int32(connect_timeout_ms, 5000, "RPC timeout in milliseconds"); | ||
DEFINE_int32(max_retry, 0, "Max retries(not including the first RPC)"); | ||
|
||
namespace brpc { | ||
const char* logo(); | ||
} | ||
|
||
// Send `command' to mysql-server via `channel' | ||
static bool access_mysql(brpc::Channel& channel, const char* command) { | ||
brpc::MysqlRequest request; | ||
if (!request.Query(command)) { | ||
LOG(ERROR) << "Fail to add command"; | ||
return false; | ||
} | ||
brpc::MysqlResponse response; | ||
brpc::Controller cntl; | ||
channel.CallMethod(NULL, &cntl, &request, &response, NULL); | ||
if (!cntl.Failed()) { | ||
std::cout << response << std::endl; | ||
} else { | ||
LOG(ERROR) << "Fail to access mysql, " << cntl.ErrorText(); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// For freeing the memory returned by readline(). | ||
struct Freer { | ||
void operator()(char* mem) { | ||
free(mem); | ||
} | ||
}; | ||
|
||
static void dummy_handler(int) {} | ||
|
||
// The getc for readline. The default getc retries reading when meeting | ||
// EINTR, which is not what we want. | ||
static bool g_canceled = false; | ||
static int cli_getc(FILE* stream) { | ||
int c = getc(stream); | ||
if (c == EOF && errno == EINTR) { | ||
g_canceled = true; | ||
return '\n'; | ||
} | ||
return c; | ||
} | ||
|
||
int main(int argc, char* argv[]) { | ||
// Parse gflags. We recommend you to use gflags as well. | ||
GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true); | ||
|
||
// A Channel represents a communication line to a Server. Notice that | ||
// Channel is thread-safe and can be shared by all threads in your program. | ||
brpc::Channel channel; | ||
|
||
// Initialize the channel, NULL means using default options. | ||
brpc::ChannelOptions options; | ||
options.protocol = brpc::PROTOCOL_MYSQL; | ||
options.connection_type = FLAGS_connection_type; | ||
options.timeout_ms = FLAGS_timeout_ms /*milliseconds*/; | ||
options.connect_timeout_ms = FLAGS_connect_timeout_ms; | ||
options.max_retry = FLAGS_max_retry; | ||
options.auth = new brpc::policy::MysqlAuthenticator( | ||
FLAGS_user, FLAGS_password, FLAGS_schema, FLAGS_params, FLAGS_collation); | ||
if (channel.Init(FLAGS_server.c_str(), FLAGS_port, &options) != 0) { | ||
LOG(ERROR) << "Fail to initialize channel"; | ||
return -1; | ||
} | ||
|
||
if (argc <= 1) { // interactive mode | ||
// We need this dummy signal hander to interrupt getc (and returning | ||
// EINTR), SIG_IGN did not work. | ||
signal(SIGINT, dummy_handler); | ||
|
||
// Hook getc of readline. | ||
rl_getc_function = cli_getc; | ||
|
||
// Print welcome information. | ||
printf("%s\n", brpc::logo()); | ||
printf( | ||
"This command-line tool mimics the look-n-feel of official " | ||
"mysql-cli, as a demostration of brpc's capability of" | ||
" talking to mysql-server. The output and behavior is " | ||
"not exactly same with the official one.\n\n"); | ||
|
||
for (;;) { | ||
char prompt[128]; | ||
snprintf(prompt, sizeof(prompt), "mysql %s> ", FLAGS_server.c_str()); | ||
std::unique_ptr<char, Freer> command(readline(prompt)); | ||
if (command == NULL || *command == '\0') { | ||
if (g_canceled) { | ||
// No input after the prompt and user pressed Ctrl-C, | ||
// quit the CLI. | ||
return 0; | ||
} | ||
// User entered an empty command by just pressing Enter. | ||
continue; | ||
} | ||
if (g_canceled) { | ||
// User entered sth. and pressed Ctrl-C, start a new prompt. | ||
g_canceled = false; | ||
continue; | ||
} | ||
// Add user's command to history so that it's browse-able by | ||
// UP-key and search-able by Ctrl-R. | ||
add_history(command.get()); | ||
|
||
if (!strcmp(command.get(), "help")) { | ||
printf("This is a mysql CLI written in brpc.\n"); | ||
continue; | ||
} | ||
if (!strcmp(command.get(), "quit")) { | ||
// Although quit is a valid mysql command, it does not make | ||
// too much sense to run it in this CLI, just quit. | ||
return 0; | ||
} | ||
access_mysql(channel, command.get()); | ||
} | ||
} else { | ||
std::string command; | ||
command.reserve(argc * 16); | ||
for (int i = 1; i < argc; ++i) { | ||
if (i != 1) { | ||
command.push_back(';'); | ||
} | ||
command.append(argv[i]); | ||
} | ||
if (!access_mysql(channel, command.c_str())) { | ||
return -1; | ||
} | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package main | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 加上license header |
||
|
||
import ( | ||
"database/sql" | ||
"flag" | ||
"fmt" | ||
_ "github.com/go-sql-driver/mysql" | ||
"log" | ||
"sync/atomic" | ||
"time" | ||
) | ||
|
||
var thread_num int | ||
|
||
func init() { | ||
flag.IntVar(&thread_num, "thread_num", 1, "thread number") | ||
} | ||
|
||
var cost int64 | ||
var qps int64 = 1 | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
db, err := sql.Open("mysql", "brpcuser:12345678@tcp(127.0.0.1:3306)/brpc_test?charset=utf8") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
for i := 0; i < thread_num; i++ { | ||
go func() { | ||
for { | ||
var ( | ||
id int | ||
col1 string | ||
col2 string | ||
col3 string | ||
col4 string | ||
) | ||
start := time.Now() | ||
rows, err := db.Query("select * from brpc_press where id = 1") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
for rows.Next() { | ||
if err := rows.Scan(&id, &col1, &col2, &col3, &col4); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
atomic.AddInt64(&cost, time.Since(start).Nanoseconds()) | ||
atomic.AddInt64(&qps, 1) | ||
} | ||
}() | ||
} | ||
|
||
var q int64 = 0 | ||
for { | ||
fmt.Println("qps =", qps-q, "latency =", cost/(qps-q)/1000) | ||
q = atomic.LoadInt64(&qps) | ||
atomic.StoreInt64(&cost, 0) | ||
time.Sleep(1 * time.Second) | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
加上license