2

Unix ドメイン タイプのソケットを開くための MySQL ユーザー定義関数を作成しました。

私の問題は、次のように関数を直接呼び出す場合です。

SELECT socketOpen("/path/to/file", "message");

常に 10 ミリ秒未満で実行されます。それはいいですね。しかし、毎回この関数を手動で呼び出したくないので、データベースに挿入してからこの関数を呼び出すストアド プロシージャを作成しました。

私が直面している問題は、ストアド プロシージャが通常10 ミリ秒未満かかることですが、1 秒を超えることもあります。5sでも。これがどのように起こるかわかりません。キャッシングの問題か何かがありますか?

以下は、明確にするためにエラーチェックを取り除いたコードです。

char *socketOpen(UDF_INIT *initid __attribute__((unused)),
               UDF_ARGS *args, char *result, unsigned long *length,
               char *is_null, char *error __attribute__((unused)))
{
    int sockfd, portno, n, servlen;
    struct sockaddr_un serv_addr;
    struct hostent *server;
    char socket_path[100];
    char message[100];

    memcpy(socket_path,args->args[0],args->lengths[0]);
    socket_path[args->lengths[0]] = 0;
    memcpy(message,args->args[1],args->lengths[1]);
    message[args->lengths[1]] = 0;

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sun_family = AF_UNIX;
    strcpy(serv_addr.sun_path, args->args[0]);

    servlen=strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);
    connect(sockfd,(struct sockaddr *) &serv_addr, servlen);

    n = write(sockfd, message, strlen(message));

    bzero(message,100);

    n = read(sockfd, message, 100);

    close(sockfd);
    strcpy(result, message);
    *length = strlen(message);
    return result;
}

この問題についての洞察をいただければ幸いです。ありがとうございました。

4

1 に答える 1

3

返信がなく、問題を修正したので、問題の解決策を共有したいと思います。

問題の原因は、私が予想していたものとはかなり異なっていました。

上記のコードを実行するマシンは Raspberry pi で、速度の遅さは考慮していませんでした。結局のところ、遅延のほとんどはプロシージャ内の UPDATE ステートメントが原因でした。テーブルのENGINEを変えたらすぐMyISAMにスムーズになりました。

ただし、コードのテスト中には、わずかな遅延が発生することもありました。ソケットをノンブロッキングにすることでそれを修正しました。つまり、何か問題が発生した場合、ソケットが開かれることはありませんが、無期限にブロックするよりはましだと思います。

于 2013-08-30T09:51:57.590 に答える