mysql的udf编程之非阻塞超时重传

MySQL的UDF(User Defined Function)类似于一种API, 用户根据一定的规范用C/C++(或采用C调用规范的语言)编写一组函数(UDF),然后编译成动态链接库,通过DROP FUNCTION语句来加载和卸载UDF。UDF被加载后可以像调用MySQL的内置函数一样来调用它,并且服务器在启动时会自动加载原来存在的UDF。

代码如下:

#ifdef STANDARD/* STANDARD is defined, don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;    /* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h>        /* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#endif
#endif
#include <mysql.h>
#include <m_ctype.h>
#include <m_string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include<fcntl.h>
#include<sys time.h="">
#include<sys ioctl.h="">
#include <sys types.h="">
#include <netinet in.h="">
#include <sys socket.h="">
#include <sys wait.h="">
#include<arpa inet.h="">
#include<unistd.h>
#include <mysql.h>
#include <ctype.h>
#ifdef HAVE_DLOPEN

my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
void http_post_deinit(UDF_INIT *initid);
longlong http_post(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);
/*************************************************************************
** Example of init function
** Arguments:
** initid                        Points to a structure that the init function should fill.
**            char *ptr;            A pointer that the function can use.
** message                        Error message
**RETURN                        This function should return 1 if something goes wrong. In this case
**************************************************************************/
my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count < 3 )
{
    strcpy(message,"Wrong arguments to http_post; ");
    return 1;
}

if(args->arg_count == 4 && args->args[3]!=NULL)
{
      int flexibleLength = strlen(args->args[3]);
      if(flexibleLength > 160000)
      {
          int allocLength = 200 + flexibleLength;
          if (!(initid->ptr=(char*) malloc(allocLength) ) )
          {
                strcpy(message,"Couldn't allocate memory in http_post_init");
                return 1;
          }
        return 0;
      }
      else
      {
          initid->ptr=NULL;
    }

}
   return 0;

}

/****************************************************************************
** Deinit function. This should all resources allocated by
** this function.
** Arguments:
** initid    Return value from xxxx_init
****************************************************************************/
void http_post_deinit(UDF_INIT *initid)
{
     if (initid!=NULL && initid->ptr!=NULL)
          {
              free(initid->ptr);
              initid->ptr = NULL;
          }

}

/***************************************************************************
** UDF string function.
** Arguments:
** initid    Structure filled by xxx_init
** args        The same structure as to xxx_init. This structure
** This function should return a pointer to the result string.
** Normally this is 'result' but may also be an alloced string.
***************************************************************************/
longlong http_post(    UDF_INIT *initid, UDF_ARGS *args,
                char *is_null __attribute__((unused)),
                char *error __attribute__((unused)))
{
    int sockfd=0;
    int numbytes=0;
    int flags=0;
    int cycletimes=0;
    char* sendBuffer=NULL;

fd_set wset;
    struct timeval tval;
    tval.tv_sec = 0;
    tval.tv_usec = 300000;

if(initid->ptr == NULL)
    {
        char sendArray[160000] = "\0";
        sendBuffer=sendArray;
    }
    else
    {
        sendBuffer = initid->ptr;
    }

struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(args->args[1]));
    serv_addr.sin_addr.s_addr = inet_addr(args->args[0]);
    bzero(&(serv_addr.sin_zero),8);

if(args->arg_count == 4 && (args->args[3]!=NULL) )
    {
        int argsNum = strlen(args->args[3]);
        sprintf(sendBuffer,"POST /?%s HTTP/1.1\r\nContent-Length:%d\r\n\r\n%s",args->args[2],argsNum,args->args[3]);
    }
    else
    {
        sprintf(sendBuffer,"POST /?%s HTTP/1.1\r\n",args->args[2]);
    }

if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        close(sockfd);
        return 2;
    }
    flags = fcntl(sockfd,F_GETFL,0);
    fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);//设置为非阻塞
    do
    {
        connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
        FD_ZERO(&wset);
        FD_SET(sockfd,&wset);
        if( select(sockfd+1, NULL, &wset, NULL,&tval) <= 0 && cycletimes==5)
        {
            close(sockfd);
            return 5;
        }
        numbytes = send(sockfd,sendBuffer,strlen(sendBuffer),0);
        if(numbytes<0)
        {
            usleep(20000);
        }
        cycletimes++;
    }while(numbytes<0 && cycletimes!=5);
    if(numbytes<0)
    {
        close(sockfd);
        return 4;
    }
    close(sockfd);
    return 0;
}
#endif /* HAVE_DLOPEN */
</ctype.h></mysql.h></unistd.h></arpa></sys></sys></netinet></sys></sys></sys></fcntl.h></unistd.h></netdb.h></errno.h></stdlib.h></m_string.h></m_ctype.h></mysql.h></string.h></m_string.h></my_sys.h></my_global.h></string.h></stdio.h></stdlib.h>

(0)

相关推荐

  • sql server 2000阻塞和死锁问题的查看与解决方法

    数据库发生阻塞和死锁的现象: 一.数据库阻塞的现象:第一个连接占有资源没有释放,而第二个连接需要获取这个资源.如果第一个连接没有提交或者回滚,第二个连接会一直等待下去,直到第一个连接释放该资源为止.对于阻塞,数据库无法处理,所以对数据库操作要及时地提交或者回滚.二.数据库死锁的现象:第一个连接占有资源没有释放,准备获取第二个连接所占用的资源,而第二个连接占有资源没有释放,准备获取第一个连接所占用的资源.这种互相占有对方需要获取的资源的现象叫做死锁.对于死锁,数据库处理方法:牺牲一个连接,保证另外

  • SqlServer中如何解决session阻塞问题

    简介 对于数据库运维人员来说创建session或者查询时产生问题是常规情况,下面介绍一种很有效且不借助第三方工具的方式来解决类似问题. 最近开始接触运维工作,所以自己总结一些方案便于不懂数据库的同事解决一些不太紧要的数据库问题.类似方法很多理论也很多,我就不做深究,就是简单写一个方案,便于菜鸟使用的. 阻塞理解 在Sql Server 中当一个数据库会话中的事务正锁定一个或多个其他会话事务想要读取或修改的资源时,会产生阻塞(Blocking).通常短时间的阻塞没有问题,且是较忙的应用程序所需要的

  • 系统隐形杀手——阻塞与等待(SQL)

    前言 应用系统承载着大量的业务,随之而来的是复杂的业务逻辑,在数据库上的表现就是有着大量的不同种类的SQL语句. SQL语句执行的快慢又与阻塞等待有着密不可分的原因. 系统慢可能有很多种原因,硬件资源不足,语句不优化,结构设计不合理,缺少必要的运维方式.所有的这些问题都可以在阻塞与等待中看出端倪,发现并解决问题. 今天这篇我们主要讲述怎么样发现并解决系统的阻塞和等待. 场景描述 您的系统是否有这样的问题? 系统运行缓慢,很多功能需要几十秒才能呈现结果,用户体验极差,领导们不断施压,作为系统的负责

  • SQL语句实现查询当前数据库IO等待状况

    sys.dm_io_pending_io_requests可以返回当前IO Pending的状态,对于SQL Server 中每个挂起的I/O 请求,返回与其对应的一行,跟sys.dm_io_virtual_file_stats配合可以看到具体是哪个数据库IO出现问题. select DB_NAME(database_id) as DBNAME, database_id, file_id, io_stall, io_pending_ms_ticks, scheduler_address from

  • sqlserver中几种典型的等待

    为了准备今年的双11很久没有更新blog,在最近的几次sqlserver问题的排查中,总结了sqlserver几种典型的等待类型,类似于oracle中的等待事件,如果看到这样的等待类型时候能够迅速定位问题的根源,下面通过一则案例来把这些典型的等待处理方法整理出来: 第一种等待.memory等待 早上接到一用户反馈其RDS实例非常的慢,通过观察sqlserver活动会话监视器(active monitor)的waiting tasks(类似于mysql的thread running)可以看到有10

  • 利用sys.sysprocesses检查SqlServer的阻塞和死锁

    MSDN:包含正在 SQL Server 实例上运行的进程的相关信息.这些进程可以是客户端进程或系统进程. 视图中主要的字段: 1. Spid:Sql Servr 会话ID 2. Kpid:Windows 线程ID 3. Blocked:正在阻塞求情的会话 ID.如果此列为 Null,则标识请求未被阻塞 4. Waittype:当前连接的等待资源编号,标示是否等待资源,0 或 Null表示不需要等待任何资源 5. Waittime:当前等待时间,单位为毫秒,0 表示没有等待 6. DBID:当前

  • SQL2008中SQL应用之-阻塞(Blocking)应用分析

    通常短时间的阻塞没有问题,且是较忙的应用程序所需要的.然而,设计糟糕的应用程序会导致长时间的阻塞,这就不必要地锁定了资源,而且阻塞了其他会话读取和更新它们. 在SQL Server中,一个阻塞的进程会无限期地保持阻塞,或者直到它超时(根据set lock_timeout).服务器关闭.进程被杀死.连接完成了更新或者其他发生在原始事务上的操作导致它释放了资源上的锁. 发生长时间阻塞的原因如下: 1.在一个没有索引的表上的过量的行锁会导致SQL Server得到一个锁,从而阻塞其他事务. 2.应用程

  • SQL Server误区30日谈 第2天 DBCC CHECKDB会导致阻塞

    误区 #2: DBCC CHECKDB会引起阻塞,因为这个命令默认会加锁 这是错误的! 在SQL Server 7.0以及之前的版本中,DBCC CHECKDB命令的本质是C语言实现的一个不断嵌套循环的代码并对表加表锁(循环嵌套算法时间复杂度是嵌套次数的N次方,作为程序员的你懂得),这种方式并不和谐,并且-.. 在SQL Server 2000时代,一个叫Steve Lindell的哥们(现在仍然在SQL Server Team)使用分析事务日志的方法来检查数据库的一致性的方式重写了DBCC C

  • SQL语句练习实例之三——平均销售等待时间

    复制代码 代码如下: ---1.平均销售等待时间 ---有一张Sales表,其中有销售日期与顾客两列,现在要求使用一条SQL语句实现计算 --每个顾客的两次购买之间的平均天数 --假设:在同一个人在一天中不会购买两次 create table sales ( custname varchar(10) not null, saledate datetime not null ) go insert sales select '张三','2010-1-1' union select '张三','20

  • mysql的udf编程之非阻塞超时重传

    MySQL的UDF(User Defined Function)类似于一种API, 用户根据一定的规范用C/C++(或采用C调用规范的语言)编写一组函数(UDF),然后编译成动态链接库,通过DROP FUNCTION语句来加载和卸载UDF.UDF被加载后可以像调用MySQL的内置函数一样来调用它,并且服务器在启动时会自动加载原来存在的UDF. 复制代码 代码如下: #ifdef STANDARD/* STANDARD is defined, don't use any mysql functio

  • 200行自定义python异步非阻塞Web框架

    Python的Web框架中Tornado以异步非阻塞而闻名.本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow. 一.源码 本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的Web框架,其中便是众多异步非阻塞Web框架内部原理. #!/usr/bin/env python # -*- coding:utf-8 -*- import re import socket import select import time class HttpResponse(object)

  • 处理java异步事件的阻塞和非阻塞方法分析

    前言 由于多核系统普遍存在,并发性编程的应用无疑比以往任何时候都要广泛.但并发性很难正确实现,用户需要借助新工具来使用它.很多基于 JVM 的语言都属于这类开发工具,Scala 在这一领域尤为活跃.本系列文章将介绍一些针对 Java 和 Scala 语言的较新的并发性编程方法. 在任何并发性应用程序中,异步事件处理都至关重要.事件来源可能是不同的计算任务.I/O 操作或与外部系统的交互.无论来源是什么,应用程序代码都必须跟踪事件,协调为响应事件而采取的操作. Java 应用程序可采用两种基本的异

  • php 多进程编程父进程的阻塞与非阻塞实例分析

    本文实例讲述了php 多进程编程父进程的阻塞与非阻塞.分享给大家供大家参考,具体如下: php中进程的阻塞,主要是父进程等待子进程退出. 1.php代码如下: <?php //定义进程数量 define('FORK_NUMS', 5); //用于保存进程pid $pids = array(); //我们创建5个子进程 for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die

  • Java异步非阻塞编程的几种方式总结

    1 服务端执行,最简单的同步调用方式: 缺陷: 服务端响应之前,IO会阻塞在: java.net.SocketInputStream#socketRead0 的native方法上: 2 JDK NIO & Future java 1.5之后 优点:主线程可以不用等待IO响应,可以去做点其他的,比如说再发送一个IO请求,可以等到一起返回; 缺点:主线程在等待结果返回过程中依然需要等待,没有根本解决此问题; 3 使用Callback回调方式 优点:主线程完成发送请求后,再也不用关心这个逻辑,去执行其

  • Java并发编程之原子变量与非阻塞同步机制

    1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 -- 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御.使用底层的原子化机器指令取代锁,比如比较并交换(CAS,compare-and-swap). 2.悲观技术 独占锁是一种悲观的技术.它假设最坏的情况发生(如果不加锁,其它线程会破坏对象状态),即使没有发生最坏的情况,仍然用锁保护对象状态.

  • python 并发编程 非阻塞IO模型原理解析

    非阻塞IO(non-blocking IO) Linux下,可以通过设置socket使其变为non-blocking.当对一个non-blocking socket执行读操作时,流程是这个样子: 从图中可以看出,当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error.从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果.用户进程判断结果是一个error时,它就知道数据还没有准备好,于是用户就可

  • 详解socket阻塞与非阻塞,同步与异步、I/O模型

    socket阻塞与非阻塞,同步与异步 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就是在c端发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 异步的概念和同步相对.当c端一个异步

  • Python中使用select模块实现非阻塞的IO

    Socket的英文原义是"孔"或"插座".作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务.Socket正如其英文原意那样,像一个多孔插座.一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110

  • PHP实现的CURL非阻塞调用类

    本文实例讲述了PHP实现的CURL非阻塞调用类.分享给大家供大家参考,具体如下: 前面一篇<PHP实现非阻塞模式的方法>文章讲述了PHP中实现非阻塞模式,其实如果只是HTTP的话,直接用CURL就能实现. 基于网上的一段代码,修改完善后封装了一个支持POST/GET的非阻塞调用类. 欢迎测试bug~~~~~ /***************************************************** CURL 非阻塞调用类 Auther: Linvo Copyright(C)

随机推荐