diff --git a/.gitignore b/.gitignore index 3f1a5d6b..90bd720f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ jtester.properties .idea/ *.iml .DS_Store +*.tar.gz +*.rpm diff --git a/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java b/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java index 88f6e9a3..0a2c91f8 100644 --- a/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java +++ b/deployer/src/main/java/com/alibaba/otter/canal/deployer/CanalController.java @@ -379,7 +379,18 @@ public class CanalController { } private String getProperty(Properties properties, String key) { - return StringUtils.trim(properties.getProperty(StringUtils.trim(key))); + key = StringUtils.trim(key); + String value = System.getProperty(key); + + if (value == null) { + value = System.getenv(key); + } + + if (value == null) { + value = properties.getProperty(key); + } + + return StringUtils.trim(value); } public void start() throws Throwable { diff --git a/deployer/src/main/resources/canal.properties b/deployer/src/main/resources/canal.properties index 0a11a5c9..2bff29ae 100644 --- a/deployer/src/main/resources/canal.properties +++ b/deployer/src/main/resources/canal.properties @@ -3,7 +3,7 @@ ################################################# canal.id= 1 canal.ip= -canal.port= 11111 +canal.port=11111 canal.zkServers= # flush data to zk canal.zookeeper.flush.period = 1000 @@ -59,6 +59,13 @@ canal.instance.parser.parallel = true ## disruptor ringbuffer size, must be power of 2 canal.instance.parser.parallelBufferSize = 256 +# table meta tsdb info +canal.instance.tsdb.enable=true +canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:} +canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL; +canal.instance.tsdb.dbUsername=canal +canal.instance.tsdb.dbPassword=canal + ################################################# ######### destinations ############# ################################################# diff --git a/deployer/src/main/resources/example/instance.properties b/deployer/src/main/resources/example/instance.properties index a3703b86..e0cf0064 100644 --- a/deployer/src/main/resources/example/instance.properties +++ b/deployer/src/main/resources/example/instance.properties @@ -1,11 +1,12 @@ ################################################# -## mysql serverId -canal.instance.mysql.slaveId=0 +## mysql serverId , v1.0.26+ will autoGen +# canal.instance.mysql.slaveId=0 + +# enable gtid use true/false +canal.instance.gtidon=false # position info canal.instance.master.address=127.0.0.1:3306 -# enable gtid use true/false -canal.instance.gtidon=false canal.instance.master.journal.name= canal.instance.master.position= canal.instance.master.timestamp= @@ -13,23 +14,21 @@ canal.instance.master.gtid= # table meta tsdb info canal.instance.tsdb.enable=true -canal.instance.tsdb.dir=${canal.file.data.dir:../conf}/${canal.instance.destination:} -canal.instance.tsdb.url=jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL; #canal.instance.tsdb.url=jdbc:mysql://127.0.0.1:3306/canal_tsdb -canal.instance.tsdb.dbUsername=canal -canal.instance.tsdb.dbPassword=canal - +#canal.instance.tsdb.dbUsername=canal +#canal.instance.tsdb.dbPassword=canal #canal.instance.standby.address = #canal.instance.standby.journal.name = #canal.instance.standby.position = #canal.instance.standby.timestamp = #canal.instance.standby.gtid= + # username/password canal.instance.dbUsername=canal canal.instance.dbPassword=canal -canal.instance.defaultDatabaseName=test canal.instance.connectionCharset=UTF-8 + # table regex canal.instance.filter.regex=.*\\..* # table black regex diff --git a/deployer/src/main/resources/spring/default-instance.xml b/deployer/src/main/resources/spring/default-instance.xml index 9bf28896..6b455c83 100644 --- a/deployer/src/main/resources/spring/default-instance.xml +++ b/deployer/src/main/resources/spring/default-instance.xml @@ -149,7 +149,7 @@ - + @@ -157,7 +157,7 @@ - + diff --git a/deployer/src/main/resources/spring/file-instance.xml b/deployer/src/main/resources/spring/file-instance.xml index 6d263717..377428a9 100644 --- a/deployer/src/main/resources/spring/file-instance.xml +++ b/deployer/src/main/resources/spring/file-instance.xml @@ -134,7 +134,7 @@ - + @@ -142,7 +142,7 @@ - + diff --git a/deployer/src/main/resources/spring/group-instance.xml b/deployer/src/main/resources/spring/group-instance.xml index 60ceff01..44f1ab3b 100644 --- a/deployer/src/main/resources/spring/group-instance.xml +++ b/deployer/src/main/resources/spring/group-instance.xml @@ -131,7 +131,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -229,7 +229,7 @@ - + @@ -237,7 +237,7 @@ - + diff --git a/deployer/src/main/resources/spring/local-instance.xml b/deployer/src/main/resources/spring/local-instance.xml index 2020d0d6..930ecb7b 100644 --- a/deployer/src/main/resources/spring/local-instance.xml +++ b/deployer/src/main/resources/spring/local-instance.xml @@ -114,7 +114,7 @@ - + diff --git a/deployer/src/main/resources/spring/memory-instance.xml b/deployer/src/main/resources/spring/memory-instance.xml index c08f3f12..cd387b8f 100644 --- a/deployer/src/main/resources/spring/memory-instance.xml +++ b/deployer/src/main/resources/spring/memory-instance.xml @@ -122,7 +122,7 @@ - + @@ -130,7 +130,7 @@ - + diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..e44796cb --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,67 @@ +FROM centos:centos6.7 + +MAINTAINER agapple (jianghang115@gmail.com) + +# install system +RUN \ + /bin/cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ + echo 'root:Hello1234' | chpasswd && \ + groupadd -r admin && useradd -g admin admin && \ + yum install -y man && \ + yum install -y dstat && \ + yum install -y unzip && \ + yum install -y nc && \ + yum install -y openssh-server && \ + yum install -y tar && \ + yum install -y which && \ + yum install -y wget && \ + yum install -y perl && \ + yum install -y file && \ + ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key && \ + ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key && \ + sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd && \ + sed -i -e 's/^#Port 22$/Port 2222/' /etc/ssh/sshd_config && \ + mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh && \ + yum install -y cronie && \ + sed -i '/session required pam_loginuid.so/d' /etc/pam.d/crond && \ + yum clean all && \ + true + +# install canal +COPY image/ /tmp/docker/ +COPY canal.deployer-*.tar.gz /home/admin/ +COPY jdk-8-linux-x64.rpm /tmp/ + +RUN \ + cp -R /tmp/docker/alidata /alidata && \ + chmod +x /alidata/bin/* && \ + mkdir -p /home/admin && \ + cp -R /tmp/docker/admin/* /home/admin/ && \ + /bin/cp -f alidata/bin/lark-wait /usr/bin/lark-wait && \ + + touch /var/lib/rpm/* && \ + yum -y install /tmp/jdk-8-linux-x64.rpm && \ + /bin/rm -f /tmp/jdk-8-linux-x64.rpm && \ + + echo "export JAVA_HOME=/usr/java/latest" >> /etc/profile && \ + echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile && \ + /bin/mv /home/admin/bin/clean_log /etc/cron.d && \ + + mkdir -p /home/admin/canal-server && \ + tar -xzvf /home/admin/canal.deployer-*.tar.gz -C /home/admin/canal-server && \ + /bin/rm -f /home/admin/canal.deployer-*.tar.gz && \ + + mkdir -p home/admin/canal-server/logs && \ + chmod +x /home/admin/*.sh && \ + chmod +x /home/admin/bin/*.sh && \ + chown admin: -R /home/admin && \ + yum clean all && \ + true + +# 2222 sys , 8080 web , 8000 debug , 11111 canal +EXPOSE 2222 11111 8000 8080 + +WORKDIR /home/admin + +ENTRYPOINT [ "/alidata/bin/main.sh" ] +CMD [ "/home/admin/app.sh" ] \ No newline at end of file diff --git a/docker/build.sh b/docker/build.sh new file mode 100644 index 00000000..58424fb3 --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +current_path=`pwd` +case "`uname`" in + Darwin) + bin_abs_path=`cd $(dirname $0); pwd` + ;; + Linux) + bin_abs_path=$(readlink -f $(dirname $0)) + ;; + *) + bin_abs_path=`cd $(dirname $0); pwd` + ;; +esac +BASE=${bin_abs_path} + +if [ ! -f $BASE/jdk*.rpm ] ; then + DOWNLOAD_LINK="http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/jdk-8u181-linux-x64.tar.gz" + wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=xxx; oraclelicense=accept-securebackup-cookie" "$DOWNLOAD_LINK" -O $BASE/jdk-8-linux-x64.rpm +fi + +cd $BASE/../ && mvn clean package -Dmaven.test.skip -Denv=release && cd $current_path ; + +if [ "$1" == "kafka" ] ; then + cp $BASE/../target/canal-kafka-*.tar.gz $BASE/ + docker build --no-cache -t canal/canal-server $BASE/ +else + cp $BASE/../target/canal.deployer-*.tar.gz $BASE/ + docker build --no-cache -t canal/canal-server $BASE/ +fi diff --git a/docker/image/admin/app.sh b/docker/image/admin/app.sh new file mode 100755 index 00000000..254f7e48 --- /dev/null +++ b/docker/image/admin/app.sh @@ -0,0 +1,117 @@ +#!/bin/bash +set -e + +source /etc/profile +export JAVA_HOME=/usr/java/latest +export PATH=$JAVA_HOME/bin:$PATH +touch /tmp/start.log +chown admin: /tmp/start.log +chown -R admin: /home/admin/canal-server +host=`hostname -i` + +# waitterm +# wait TERM/INT signal. +# see: http://veithen.github.io/2014/11/16/sigterm-propagation.html +waitterm() { + local PID + # any process to block + tail -f /dev/null & + PID="$!" + # setup trap, could do nothing, or just kill the blocker + trap "kill -TERM ${PID}" TERM INT + # wait for signal, ignore wait exit code + wait "${PID}" || true + # clear trap + trap - TERM INT + # wait blocker, ignore blocker exit code + wait "${PID}" 2>/dev/null || true +} + +# waittermpid "${PIDFILE}". +# monitor process by pidfile && wait TERM/INT signal. +# if the process disappeared, return 1, means exit with ERROR. +# if TERM or INT signal received, return 0, means OK to exit. +waittermpid() { + local PIDFILE PID do_run error + PIDFILE="${1?}" + do_run=true + error=0 + trap "do_run=false" TERM INT + while "${do_run}" ; do + PID="$(cat "${PIDFILE}")" + if ! ps -p "${PID}" >/dev/null 2>&1 ; then + do_run=false + error=1 + else + sleep 1 + fi + done + trap - TERM INT + return "${error}" +} + + +function checkStart() { + local name=$1 + local cmd=$2 + local timeout=$3 + cost=5 + while [ $timeout -gt 0 ]; do + ST=`eval $cmd` + if [ "$ST" == "0" ]; then + sleep 1 + let timeout=timeout-1 + let cost=cost+1 + elif [ "$ST" == "" ]; then + sleep 1 + let timeout=timeout-1 + let cost=cost+1 + else + break + fi + done + echo "start $name successful" +} + + +function start_canal() { + echo "start canal ..." + serverPort=`perl -le 'print $ENV{"canal.port"}'` + if [ -z "$serverPort" ] ; then + serverPort=11111 + fi + + destination=`perl -le 'print $ENV{"canal.destinations"}'` + if [[ "$destination" =~ ',' ]]; then + echo "multi destination:$destination is not support" + exit 1; + else + mv /home/admin/canal-server/conf/example /home/admin/canal-server/conf/$destination + fi + su admin -c 'cd /home/admin/canal-server/bin/ && sh restart.sh 1>>/tmp/start.log 2>&1' + sleep 5 + #check start + checkStart "canal" "nc 127.0.0.1 $serverPort -w 1 -z | wc -l" 30 +} + +function stop_canal() { + echo "stop canal" + su admin -c 'cd /home/admin/canal-server/bin/ && sh stop.sh 1>>/tmp/start.log 2>&1' + echo "stop canal successful ..." +} + +echo "==> START ..." + +start_canal + +echo "==> START SUCCESSFUL ..." + +tail -f /dev/null & +# wait TERM signal +waitterm + +echo "==> STOP" + +stop_canal + +echo "==> STOP SUCCESSFUL ..." diff --git a/docker/image/admin/bin/clean_log b/docker/image/admin/bin/clean_log new file mode 100644 index 00000000..df183614 --- /dev/null +++ b/docker/image/admin/bin/clean_log @@ -0,0 +1,2 @@ +# cron clean log once per minute +*/2 * * * * admin /home/admin/bin/clean_log.sh >>/tmp/clean_log.log 2>&1 diff --git a/docker/image/admin/bin/clean_log.sh b/docker/image/admin/bin/clean_log.sh new file mode 100755 index 00000000..9d0a0bef --- /dev/null +++ b/docker/image/admin/bin/clean_log.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Global Settings +PATH="$HOME/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin" +export PATH + +CUTOFF="85" +#获取磁盘使用率最高的分区 +USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1) +before=$USAGE + +baseClean(){ + #删除tmp目录15天前的文件。 + #更新文档时间戳 + if [ -d /tmp/hsperfdata_admin ] + then + touch /tmp/hsperfdata_admin + touch /tmp/hsperfdata_admin/* + fi + + find /tmp/ -type f -mtime +15 | xargs -t rm -rf >/dev/null 2>&1 + + + now=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1) + echo "before:$before; now:$now" +} + +CANAL_DIR="/home/admin/canal-server/logs" +if [[ -d $CANAL_DIR ]]; then + USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1) + if [[ $USAGE -ge 90 ]]; then + find $CANAL_DIR -type f -mtime +7 | xargs rm -rf {} + fi + USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1) + if [[ $USAGE -ge 80 ]]; then + find $CANAL_DIR -type f -mtime +3 | xargs rm -rf {} + fi + USAGE=$(df -h|awk 'NR>1 {gsub(/%$/,"",$5);print $5 }'|sort -nr|head -1) + if [[ $USAGE -ge 80 ]]; then + find $CANAL_DIR -type d -empty -mtime +3 | grep -v canal | xargs rm -rf {} + find $CANAL_DIR -type f -iname '*.tmp' | xargs rm -rf {} + fi + baseClean + exit 0 +fi \ No newline at end of file diff --git a/docker/image/admin/health.sh b/docker/image/admin/health.sh new file mode 100755 index 00000000..17a89740 --- /dev/null +++ b/docker/image/admin/health.sh @@ -0,0 +1,13 @@ +#!/bin/sh +CHECK_URL="http://127.0.0.1:8080/metrics" +CHECK_POINT="success" +CHECK_COUNT=`curl -s --connect-timeout 7 --max-time 7 $CHECK_URL | grep -c $CHECK_POINT` +if [ $CHECK_COUNT -eq 0 ]; then + echo "[FAILED]" + status=0 + error=1 +else + echo "[ OK ]" + status=1 + error=0 +fi \ No newline at end of file diff --git a/docker/image/alidata/bin/exec_rc_local.sh b/docker/image/alidata/bin/exec_rc_local.sh new file mode 100755 index 00000000..7cc8aa3f --- /dev/null +++ b/docker/image/alidata/bin/exec_rc_local.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ "${SKIP_EXEC_RC_LOCAL}" = "YES" ] ; then + echo "skip /etc/rc.local: SKIP_EXEC_RC_LOCAL=${SKIP_EXEC_RC_LOCAL}" + exit +fi + +if [ "${DOCKER_DEPLOY_TYPE}" = "HOST" ] ; then + echo "skip /etc/rc.local: DOCKER_DEPLOY_TYPE=${DOCKER_DEPLOY_TYPE}" + exit +fi \ No newline at end of file diff --git a/docker/image/alidata/bin/lark-wait b/docker/image/alidata/bin/lark-wait new file mode 100755 index 00000000..db7be708 --- /dev/null +++ b/docker/image/alidata/bin/lark-wait @@ -0,0 +1,6 @@ +#!/bin/bash +set -e + +chown admin: -R /home/admin/ +source /alidata/lib/proc.sh +waitterm diff --git a/docker/image/alidata/bin/main.sh b/docker/image/alidata/bin/main.sh new file mode 100755 index 00000000..a57551a7 --- /dev/null +++ b/docker/image/alidata/bin/main.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +[ -n "${DOCKER_DEPLOY_TYPE}" ] || DOCKER_DEPLOY_TYPE="VM" +echo "DOCKER_DEPLOY_TYPE=${DOCKER_DEPLOY_TYPE}" + +# run init scripts +for e in $(ls /alidata/init/*) ; do + [ -x "${e}" ] || continue + echo "==> INIT $e" + $e + echo "==> EXIT CODE: $?" +done + +echo "==> INIT DEFAULT" +service sshd start +service crond start + +#echo "check hostname -i: `hostname -i`" +#hti_num=`hostname -i|awk '{print NF}'` +#if [ $hti_num -gt 1 ];then +# echo "hostname -i result error:`hostname -i`" +# exit 120 +#fi + +echo "==> INIT DONE" +echo "==> RUN ${*}" +exec "${@}" \ No newline at end of file diff --git a/docker/image/alidata/init/02init-sshd.sh b/docker/image/alidata/init/02init-sshd.sh new file mode 100755 index 00000000..118ee553 --- /dev/null +++ b/docker/image/alidata/init/02init-sshd.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# set port +if [ -z "${SSHD_PORT}" ] ; then + SSHD_PORT=22 + [ "${DOCKER_DEPLOY_TYPE}" = "HOST" ] && SSHD_PORT=2222 +fi + +sed -r -i '/^OPTIONS=/ d' /etc/sysconfig/sshd +echo 'OPTIONS="-p '"${SSHD_PORT}"'"' >> /etc/sysconfig/sshd + +# set admin ssh pulic key +if [ "${USE_ADMIN_PASSAGE}" = "YES" ] ; then + echo "set admin passage" + mkdir -p /home/admin/.ssh + chown admin:admin /home/admin/.ssh + chown admin:admin /home/admin/.ssh/authorized_keys + chmod 644 /home/admin/.ssh/authorized_keys +fi diff --git a/docker/image/alidata/init/fix-hosts.py b/docker/image/alidata/init/fix-hosts.py new file mode 100755 index 00000000..4ee8abb5 --- /dev/null +++ b/docker/image/alidata/init/fix-hosts.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +#****************************************************************# +# Create Date: 2017-01-06 17:58 +#***************************************************************# + +import socket +import shutil +from time import gmtime, strftime + +# get host_name +host_name = socket.gethostname() +tmp_file = "/tmp/.lark-fix-host.hosts" +host_file = "/etc/hosts" +bak_file_name = "/tmp/hosts-fix-bak.%s" % ( strftime("%Y-%m-%d_%H-%M-%S", gmtime()) ) + +# load /etc/hosts file context +FH = open(host_file,"r") +file_lines = [ i.rstrip() for i in FH.readlines()] +FH.close() +file_lines_reverse = file_lines[::-1] +new_lines = [] +bad_lines = [] +last_match_line = "" + +for line in file_lines_reverse: + if line.find(host_name) < 0: # 不匹配的行直接跳过 + new_lines.append(line + "\n") + continue + + cols = line.split() + new_cols = [] + if cols[0].startswith("#"): # 跳过已经注释掉的行 + new_lines.append(line + "\n") + continue + for col in cols: + if not col == host_name: # 跳过不匹配的列 + new_cols.append(col) + continue + + if cols[0] == "127.0.0.1": # 如果第一列是 127.0.0.1 就跳过匹配的列, 防止 hostname -i 返回 127.0.0.1 + continue + + # 如果已经发现过匹配的列, 就丢掉重复的列 + if not len(last_match_line) == 0: + continue + + new_cols.append(col) + last_match_line = line + + # 跳过 xx.xx.xx.xx hostname 这样的重复列 + if len(new_cols) == 1: + continue + + new_l = "%s\n" % " ".join(new_cols) + new_lines.append(new_l) + +# save tmp hosts + +FH2=file(tmp_file,"w+") +FH2.writelines( new_lines[::-1]) +FH2.close() + +# mv to /etc/hosts +shutil.copy(host_file, bak_file_name) +shutil.move(tmp_file, host_file) diff --git a/docker/image/alidata/lib/proc.sh b/docker/image/alidata/lib/proc.sh new file mode 100644 index 00000000..40ddff93 --- /dev/null +++ b/docker/image/alidata/lib/proc.sh @@ -0,0 +1,40 @@ +# waitterm +# wait TERM/INT signal. +# see: http://veithen.github.io/2014/11/16/sigterm-propagation.html +waitterm() { + local PID + # any process to block + tail -f /dev/null & + PID="$!" + # setup trap, could do nothing, or just kill the blocker + trap "kill -TERM ${PID}" TERM INT + # wait for signal, ignore wait exit code + wait "${PID}" || true + # clear trap + trap - TERM INT + # wait blocker, ignore blocker exit code + wait "${PID}" 2>/dev/null || true +} + +# waittermpid "${PIDFILE}". +# monitor process by pidfile && wait TERM/INT signal. +# if the process disappeared, return 1, means exit with ERROR. +# if TERM or INT signal received, return 0, means OK to exit. +waittermpid() { + local PIDFILE PID do_run error + PIDFILE="${1?}" + do_run=true + error=0 + trap "do_run=false" TERM INT + while "${do_run}" ; do + PID="$(cat "${PIDFILE}")" + if ! ps -p "${PID}" >/dev/null 2>&1 ; then + do_run=false + error=1 + else + sleep 1 + fi + done + trap - TERM INT + return "${error}" +} diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 00000000..7c56e2ba --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +function usage() { + echo "Usage:" + echo " run.sh [CONFIG]" + echo "example:" + echo " run.sh -e canal.instance.master.address=127.0.0.1:3306 \\" + echo " -e canal.instance.dbUsername=canal \\" + echo " -e canal.instance.dbPassword=canal \\" + echo " -e canal.instance.connectionCharset=UTF-8 \\" + echo " -e canal.instance.tsdb.enable=true \\" + echo " -e canal.instance.gtidon=false \\" + echo " -e canal.instance.filter.regex=.*\\..* " + exit +} + +function check_port() { + local port=$1 + local TL=$(which telnet) + if [ -f $TL ]; then + data=`echo quit | telnet 127.0.0.1 $port| grep -ic connected` + echo $data + return + fi + + local NC=$(which nc) + if [ -f $NC ]; then + data=`nc -z -w 1 127.0.0.1 $port | grep -ic succeeded` + echo $data + return + fi + echo "0" + return +} + +function getMyIp() { + case "`uname`" in + Darwin) + myip=`echo "show State:/Network/Global/IPv4" | scutil | grep PrimaryInterface | awk '{print $3}' | xargs ifconfig | grep inet | grep -v inet6 | awk '{print $2}'` + ;; + *) + myip=`ip route get 1 | awk '{print $NF;exit}'` + ;; + esac + echo $myip +} + +NET_MODE="" +case "`uname`" in + Darwin) + bin_abs_path=`cd $(dirname $0); pwd` + ;; + Linux) + bin_abs_path=$(readlink -f $(dirname $0)) + NET_MODE="--net=host" + ;; + *) + NET_MODE="--net=host" + bin_abs_path=`cd $(dirname $0); pwd` + ;; +esac +BASE=${bin_abs_path} +if [ $# -eq 0 ]; then + usage +elif [ "$1" == "-h" ] ; then + usage +elif [ "$1" == "help" ] ; then + usage +fi + +DATA="$BASE/data" +mkdir -p $DATA +CONFIG=${@:1} +#VOLUMNS="-v $DATA:/home/admin/canal-server/logs" +PORTLIST="8000 8080 2222 11111" +PORTS="" +for PORT in $PORTLIST ; do + #exist=`check_port $PORT` + exist="0" + if [ "$exist" == "0" ]; then + PORTS="$PORTS -p $PORT:$PORT" + else + echo "port $PORT is used , pls check" + exit 1 + fi +done + +MEMORY="-m 4096m" +LOCALHOST=`getMyIp` +cmd="docker run -it -h $LOCALHOST $CONFIG --name=canal-server $VOLUMNS $NET_MODE $PORTS $MEMORY canal/canal-server" +echo $cmd +eval $cmd \ No newline at end of file diff --git a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java index 29b96852..0f01cbd5 100644 --- a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java +++ b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java @@ -32,7 +32,7 @@ public class MysqlConnector { private String password; private byte charsetNumber = 33; - private String defaultSchema = "retl"; + private String defaultSchema = "test"; private int soTimeout = 30 * 1000; private int connTimeout = 5 * 1000; private int receiveBufferSize = 16 * 1024; diff --git a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java b/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java index 6c2b9d4d..e640364f 100644 --- a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java +++ b/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java @@ -643,6 +643,9 @@ public class MysqlEventParser extends AbstractMysqlEventParser implements CanalE throw new CanalParseException("command : 'show master status' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation"); } EntryPosition endPosition = new EntryPosition(fields.get(0), Long.valueOf(fields.get(1))); + if (isGTIDMode && fields.size() > 4) { + endPosition.setGtid(fields.get(4)); + } return endPosition; } catch (IOException e) { throw new CanalParseException("command : 'show master status' has an error!", e);